From 2505e2cbf4cc2fd20f8443555a0e0476ce4e0bea Mon Sep 17 00:00:00 2001 From: Lukas Heiligenbrunner Date: Fri, 1 May 2020 15:33:20 +0200 Subject: [PATCH] new option to verify syntax and parameters of config file cdoc for logging class --- CMakeLists.txt | 10 +++++++-- inc/Config.h | 12 +++++++++++ inc/Logger.h | 25 +++++++++++++++++++++++ src/Config.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++----- src/Logger.cpp | 3 +++ src/api/API.cpp | 3 --- src/main.cpp | 10 ++++++++- 7 files changed, 106 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e5b8bb8..c10cee9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,12 @@ -# author Lukas Heiligenbrunner +# @author Lukas Heiligenbrunner # main CMake file # +# Build lib dependencies: +## libcurl (with sources) +## libconfig (with sources) +# +# documenation build needs doxygen to be installed. + cmake_minimum_required(VERSION 3.13) project(iprefresher DESCRIPTION "Dynu ip refresher") @@ -8,7 +14,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_BUILD_TYPE Release) # manually set build type (Release / Debug) set(LIB_METHOD STATIC) #SHARED / STATIC -set(PROJECT_VERSION 1.3.1) +set(PROJECT_VERSION 1.3.1-dev) option(BUILD_DOC "Build documentation" ON) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) diff --git a/inc/Config.h b/inc/Config.h index 1c9b728..1107e14 100644 --- a/inc/Config.h +++ b/inc/Config.h @@ -16,7 +16,19 @@ public: static std::string telegramApiKey; static std::string chatId; + /** + * read configuration out of config file + * + * @return success of config read + */ static bool readCredentials(); + /** + * validate config file + * + * @return validity of config file + */ + static bool validateConfig(); + private: }; \ No newline at end of file diff --git a/inc/Logger.h b/inc/Logger.h index d486f93..e0ffccf 100644 --- a/inc/Logger.h +++ b/inc/Logger.h @@ -8,13 +8,38 @@ class Logger { public: + /** + * a debug message + * @param message message + */ static void debug(std::string message); + + /** + * a default message + * @param message message + */ static void message(std::string message); + + /** + * a warning message + * @param message message + */ static void warning(std::string message); + + /** + * a error message + * @param message message + */ static void error(std::string message); + /** + * a log message with manual level set + * @param message message + * @param level loglevel (1-4) or predefined labels + */ static void log(const std::string &message, int level); + static const int Debug = 4; static const int Message = 3; static const int Warning = 2; diff --git a/src/Config.cpp b/src/Config.cpp index 335d9ab..9a07099 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -3,11 +3,12 @@ // #include +#include + #include #include #include - -#include "libconfig.h++" +#include std::string Config::dynuapikey; std::string Config::domainid; //id of the dynu domain @@ -40,14 +41,13 @@ domainname = "" std::ofstream myfile; myfile.open("/etc/iprefresher.cfg"); - if(myfile.is_open()){ + if (myfile.is_open()) { myfile << defaultconf; myfile.close(); } else { std::cout << "error creating file" << std::endl; } - return false; } catch (const libconfig::ParseException &pex) { @@ -56,7 +56,6 @@ domainname = "" return false; } - // Get the store name. try { // needed parameters dynuapikey = (std::string) cfg.lookup("dynuapikey"); @@ -75,3 +74,48 @@ domainname = "" // check if needed values aren't empty return !(Config::dynuapikey.empty() || Config::domainid.empty() || Config::domainname.empty()); } + +bool Config::validateConfig() { + libconfig::Config cfg; + try { + Logger::message("reading config file"); + cfg.readFile("/etc/iprefresher.cfg"); + } + catch (const libconfig::FileIOException &fioex) { + Logger::warning("config file doesn't exist or permission denied!"); + return false; + } + catch (const libconfig::ParseException &pex) { + std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() + << " - " << pex.getError() << std::endl; + return false; + } + Logger::message("Syntax and Permission is OK"); + + try { + // needed parameters + if (((std::string) cfg.lookup("dynuapikey")).empty()) { + Logger::warning("required parameter dynuapikey seems to be empty."); + return false; + } + if (((std::string) cfg.lookup("domainid")).empty()) { + Logger::warning("required parameter domainid seems to be empty."); + return false; + } + if (((std::string) cfg.lookup("domainname")).empty()) { + Logger::warning("required parameter domainname seems to be empty."); + return false; + } + // optional parameters + cfg.lookup("telegramApiKey"); + cfg.lookup("chatId"); + } + catch (const libconfig::SettingNotFoundException &nfex) { + // triggered if setting is missing in config + if (!(std::strcmp("telegramApiKey", nfex.getPath()) == 0 || std::strcmp("chatId", nfex.getPath()) == 0)) { + std::cerr << "No '" << nfex.getPath() << "' setting in configuration file." << std::endl; + return false; + } + } + return true; +} \ No newline at end of file diff --git a/src/Logger.cpp b/src/Logger.cpp index 6822bf0..77a81ca 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -39,6 +39,9 @@ void Logger::log(const std::string &message, int level) { case Error: out << "ERROR"; break; + default: + out << "UNDEFINED"; + break; } out << "] "; out << message; diff --git a/src/api/API.cpp b/src/api/API.cpp index 768345b..e246450 100644 --- a/src/api/API.cpp +++ b/src/api/API.cpp @@ -3,10 +3,7 @@ // #include "api/API.h" -#include "api/Hashmap.h" -#include -#include #include #include diff --git a/src/main.cpp b/src/main.cpp index d2858f5..4eb5fec 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,12 +2,12 @@ // Created by lukas on 18.06.19. // -#include #include #include #include #include +#include /** * application entry point */ @@ -19,6 +19,7 @@ int main(int argc, char *argv[]) { << "[-v] [--version] print the software version" << std::endl << "[-f] [--force] force refresh of ip" << std::endl << "[-l] [--loop] infinite loop to refresh ip every five minutes" << std::endl + << "[-c] [--checkconfig] validate configuration" << std::endl << "[no argument] normal ip check and refresh" << std::endl; } else if (firstarg == "-v" || firstarg == "--version") { std::cout << "Version " << Version::VERSION << std::endl; @@ -32,6 +33,13 @@ int main(int argc, char *argv[]) { } else if (firstarg == "-l" || firstarg == "--loop") { IPRefresher(true); + } else if (firstarg == "-c" || firstarg == "--checkconfig") { + if (Config::validateConfig()) { + Logger::message("Config file is OK"); + } else { + Logger::warning("There are errors in config file!"); + return -1; + } } else { Logger::message("wrong arguments! -h for help"); }