diff --git a/CMakeLists.txt b/CMakeLists.txt index 27a3ac6..9e4a5ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ project(dynuiprefresher DESCRIPTION "Dynu ip refresher" LANGUAGES) SET(PROJECT_VERSION 1.3.4) # CONFIGURATION -SET(CMAKE_BUILD_TYPE Release) # manually SET build type (Release / Debug) +SET(CMAKE_BUILD_TYPE Debug) # manually SET build type (Release / Debug) SET(LIB_METHOD STATIC) #SHARED / STATIC option(BUILD_DOC "Build documentation" ON) # additional dependency for Doxygen @@ -93,61 +93,9 @@ enable_language(C) # config libs message("") message(STATUS "Config of Libraries") -# libcurl -if (${WinBuild}) - SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll") - # configure libcurl - FIND_PATH(CURL_INCLUDE_DIRS curl/curl.h /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/include/) # search for libconfig include headers - FIND_LIBRARY(CURL_LIBRARIES NAMES libcurl.dll.a HINTS /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib) # search for actual lib - message(STATUS "Using CURL include dir(s): ${CURL_INCLUDE_DIRS}") - message(STATUS "Using CURL lib(s): ${CURL_LIBRARIES}") - message(STATUS "") - - include_directories(${CURL_INCLUDE_DIRS}) - - # configure libconfig - FIND_PATH(LIBCONFIG++_INCLUDE_DIRS libconfig.h++ /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/include/) # search for libconfig include headers - FIND_LIBRARY(LIBCONFIG++_LIBRARIES NAMES libconfig++.dll.a HINTS /usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib) # search for actual lib - - message(STATUS "Using LIBCONFIG++ include dir(s): ${LIBCONFIG++_INCLUDE_DIRS}") - message(STATUS "Using LIBCONFIG++ lib(s): ${LIBCONFIG++_LIBRARIES}") - - if (${GUI}) - set(CMAKE_PREFIX_PATH "/usr/${TOOLCHAIN_PREFIX}/sys-root/mingw/lib/cmake") - endif () - - include_directories(${LIBCONFIG++_INCLUDE_DIRS}) -else () - find_package(CURL REQUIRED) - if (CURL_INCLUDE_DIRS AND CURL_LIBRARIES) - message(STATUS "Found CURL version: ${CURL_VERSION_STRING}") - message(STATUS "Using CURL include dir(s): ${CURL_INCLUDE_DIRS}") - message(STATUS "Using CURL lib(s): ${CURL_LIBRARIES}") - else () - message(FATAL_ERROR "Could not find CURL") - endif () - include_directories(${CURL_INCLUDE_DIR}) - - message("") - # libconfig - FIND_PATH(LIBCONFIG++_INCLUDE_DIRS - NAMES libconfig.h++ - PATHS /usr/include /usr/local/include) # search for libconfig include headers - FIND_LIBRARY(LIBCONFIG++_LIBRARIES - NAMES config++ - PATHS /usr/lib /usr/local/lib) # search for actual lib - - if (LIBCONFIG++_INCLUDE_DIRS AND LIBCONFIG++_LIBRARIES) - message(STATUS "Fount libconfig!") - message(STATUS "Using libconfig include dir(s): ${LIBCONFIG++_INCLUDE_DIRS}") - message(STATUS "Using libconfig lib(s): ${LIBCONFIG++_LIBRARIES}") - else () - message(FATAL_ERROR "Could not find LIBCONFIG") - endif () - - include_directories(${LIBCONFIG_INCLUDE_DIRS}) -endif () +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) if (${GUI}) @@ -196,16 +144,15 @@ add_library(api ${LIB_METHOD} add_library(libdynuiprefresher ${LIB_METHOD} src/IPRefresher.cpp - src/Config.cpp src/IpHelper.cpp src/FileLogger.cpp src/Logger.cpp - ) + src/ConfigParser.cpp) add_executable(${Application_Name} src/main.cpp) # LINK generated LIBS # -target_link_libraries(${Application_Name} libdynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES}) +target_link_libraries(${Application_Name} libdynuiprefresher api CONAN_PKG::libcurl) if (${GUI}) set(QT5_LIBRARIES Qt5::Widgets Qt5::PrintSupport Qt5::Sql) @@ -232,7 +179,7 @@ if (${GUI}) endif () # LINK generated LIBS # - target_link_libraries(${Application_Name}-gui -lpthread libdynuiprefresher api ${CURL_LIBRARIES} ${LIBCONFIG++_LIBRARIES} ${QT5_LIBRARIES}) + target_link_libraries(${Application_Name}-gui -lpthread libdynuiprefresher api CONAN_PKG::libcurl ${QT5_LIBRARIES}) endif () # setting install targets diff --git a/conanfile.txt b/conanfile.txt new file mode 100644 index 0000000..eb064c5 --- /dev/null +++ b/conanfile.txt @@ -0,0 +1,6 @@ + [requires] + libcurl/7.72.0@heili/release + + [generators] + cmake + diff --git a/inc/Config.h b/inc/Config.h deleted file mode 100644 index db806e7..0000000 --- a/inc/Config.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * A static class to manage the configuration file, read/write parameters to it. - * - * @author Lukas Heiligenbrunner - * @date 11.02.2020 - */ - -#pragma once - -#include - -class Config { -public: - /** - * read configuration out of config file - * - * @return success of config read - */ - static bool readConfig(); - - /** - * save back configuration to file - * - * @return success of config write - */ - static bool saveConfig(); - - /** - * validate config file - * - * @return validity of config file - */ - static bool validateConfig(); - - /** - * check if telegram credentials in config are set - * @return is supported? - */ - static bool isTelegramSupported(); - - /** Getters **/ - - /** - * encapsulated getter for DynuApiKey - * @return api key - */ - static const std::string &getDynuapikey(); - - /** - * encapsulated getter for DomainId - * @return DomainId - */ - static const std::string &getDomainid(); - - /** - * encapsulated getter for Domainname - * @return Domainname - */ - static const std::string &getDomainname(); - - /** - * encapsulated getter for TelegramApiKey - * @return TelegramApiKey - */ - static const std::string &getTelegramApiKey(); - - /** - * encapsulated getter for ChatId - * @return ChatId - */ - static const std::string &getChatId(); - - /** - * set all parameters without telegram support - * - * @param domainname Dynu Domain name - * @param dynuapikey Dynu api key - * @param domainid Dynu domain id - */ - static void setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid); - - /** - * set all parameters with telegram support - * - * @param domainname Dynu Domain name - * @param dynuapikey Dynu api key - * @param domainid Dynu domain id - * @param telegramApiKey Telegram api key - * @param chatId Telegram chat id - */ - static void setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid, - const std::string &telegramApiKey, const std::string &chatId); - -private: - /** - * private constructor --> don't allow instance of this class - */ - Config() = default; - - /** - * helper variable for managing telegram Support - */ - static bool telegramSupport; - - /** - * helper variables for storing keys and ids - */ - static std::string dynuapikey; - static std::string domainid; //id of the dynu domain - static std::string domainname; - static std::string telegramApiKey; - static std::string chatId; -}; \ No newline at end of file diff --git a/inc/ConfigParser.h b/inc/ConfigParser.h new file mode 100644 index 0000000..8f4dc6a --- /dev/null +++ b/inc/ConfigParser.h @@ -0,0 +1,51 @@ +// +// Created by lukas on 09.10.20. +// + +#pragma once + + +class ConfigParser { +public: + static bool loadConfig(); + bool saveConfig(); + static bool validateConfig(); + + /** + * check if telegram credentials in config are set + * @return is supported? + */ + static bool isTelegramSupported(); + + /** Getters **/ + + /** + * encapsulated getter for DynuApiKey + * @return api key + */ + static const std::string &getDynuapikey(); + + /** + * encapsulated getter for DomainId + * @return DomainId + */ + static const std::string &getDomainid(); + + /** + * encapsulated getter for Domainname + * @return Domainname + */ + static const std::string &getDomainname(); + + /** + * encapsulated getter for TelegramApiKey + * @return TelegramApiKey + */ + static const std::string &getTelegramApiKey(); + + /** + * encapsulated getter for ChatId + * @return ChatId + */ + static const std::string &getChatId(); +}; diff --git a/src/Config.cpp b/src/Config.cpp deleted file mode 100644 index 80cb95f..0000000 --- a/src/Config.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include "Config.h" -#include "Logger.h" -#include "StaticData.h" - -#include -#include -#include -#include -#include - -std::string Config::dynuapikey; -std::string Config::domainid; //id of the dynu domain -std::string Config::domainname; - -std::string Config::telegramApiKey; -std::string Config::chatId; - -bool Config::telegramSupport; - -bool Config::readConfig() { - libconfig::Config cfg; - try { - cfg.readFile(std::string(StaticData::ConfigDir + StaticData::ConfName).c_str()); - } - catch (const libconfig::FileIOException &fioex) { - std::cout << "I/O error while reading config file." << std::endl << "creating new config file!" << std::endl; - - // check if config folder exists - struct stat info{}; - - if (stat(StaticData::ConfigDir.c_str(), &info) != 0) { - Logger::warning("The config folder doesn't exist. Trying to create it."); - -// mkdir command is different defined for windows -#ifdef __unix - int check = mkdir(StaticData::ConfigDir.c_str(), 777); -#else - int check = mkdir(StaticData::ConfigDir.c_str()); -#endif - - // check if directory is created or not - if (!check) - Logger::message("config directory successfully created. "); - else - Logger::error("unable to create config directory."); - - } else if (info.st_mode & S_IFDIR) { - Logger::debug("config directory exists already"); - } else { - Logger::error("A file exists with the same name as the config dir should be"); - } - - - std::ofstream myfile; - myfile.open(StaticData::ConfigDir + StaticData::ConfName); - if (myfile.is_open()) { - myfile << StaticData::SAMPLECONFIG; - myfile.close(); - } else { - Logger::error("error creating file"); - } - - return false; - } - catch (const libconfig::ParseException &pex) { - std::cerr << "Parse error at " << pex.getFile() << ":" << pex.getLine() - << " - " << pex.getError() << std::endl; - return false; - } - - try { - // needed parameters - dynuapikey = (std::string) cfg.lookup("dynuapikey"); - domainid = (std::string) cfg.lookup("domainid"); - domainname = (std::string) cfg.lookup("domainname"); - // optional parameters - telegramApiKey = (std::string) cfg.lookup("telegramApiKey"); - chatId = (std::string) cfg.lookup("chatId"); - telegramSupport = true; - } - 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; - } else { - Logger::message("no Telegram support - fields in config not set"); - telegramSupport = false; - } - } - // check if needed values aren't empty - return !(Config::dynuapikey.empty() || Config::domainid.empty() || Config::domainname.empty()); -} - -bool Config::saveConfig() { - // todo save config - return false; -} - -bool Config::validateConfig() { - libconfig::Config cfg; - try { - Logger::message("reading config file"); - cfg.readFile(std::string(StaticData::ConfigDir + StaticData::ConfName).c_str()); - } - 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"); - telegramSupport = true; - } - 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; - } else { - Logger::message("no Telegram support - fields in config not set"); - telegramSupport = false; - } - } - return true; -} - -bool Config::isTelegramSupported() { - return telegramSupport; -} - -const std::string &Config::getDynuapikey() { - return dynuapikey; -} - -const std::string &Config::getDomainid() { - return domainid; -} - -const std::string &Config::getDomainname() { - return domainname; -} - -const std::string &Config::getTelegramApiKey() { - return telegramApiKey; -} - -const std::string &Config::getChatId() { - return chatId; -} - -void Config::setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid) { - Config::domainname = domainname; - Config::dynuapikey = dynuapikey; - Config::domainid = domainid; -} - -void Config::setValues(const std::string &domainname, const std::string &dynuapikey, const std::string &domainid, const std::string &telegramApiKey, const std::string &chatId) { - setValues(domainname, dynuapikey, domainid); - Config::telegramApiKey = telegramApiKey; - Config::chatId = chatId; -} diff --git a/src/ConfigParser.cpp b/src/ConfigParser.cpp new file mode 100644 index 0000000..faefd25 --- /dev/null +++ b/src/ConfigParser.cpp @@ -0,0 +1,81 @@ +// +// Created by lukas on 09.10.20. +// + +#include +#include +#include +#include +#include +#include "inc/ConfigParser.h" + +bool ConfigParser::loadConfig() { + const std::string config = StaticData::ConfigDir + StaticData::ConfName; + + const std::regex matchcomment(R"(^\s*#)"); // match hash to be a comment line + const std::regex matchkey(R"(.+(?=\=.+))"); + const std::regex matchvalue(R"((?:=(.+)(?=\s*#*)))"); + + std::map entries; + + std::ifstream myfile(config); + if (myfile.is_open()) { + std::string line; + + while (getline(myfile, line)) { + if (std::regex_search(line, matchcomment) || line == "") { + // comment line + continue; + } + + // parse a key value pair + std::smatch mk, mv; + std::regex_search(line, mk, matchkey); + std::regex_search(line, mv, matchvalue); + + if (!mk.empty() && !mv.empty()){ + entries.insert(std::pair(mk[0], mv[0])); + std::cout << mk[0] << "--" << mv[0] << std::endl; + } + + + } + myfile.close(); + } else return false; + + return true; +} + +bool ConfigParser::saveConfig() { + // todo + return false; +} + +bool ConfigParser::validateConfig() { + // todo + return false; +} + +bool ConfigParser::isTelegramSupported() { + return false; +} + +const std::string &ConfigParser::getDynuapikey() { + return ""; +} + +const std::string &ConfigParser::getDomainid() { + return ""; +} + +const std::string &ConfigParser::getDomainname() { + return ""; +} + +const std::string &ConfigParser::getTelegramApiKey() { + return ""; +} + +const std::string &ConfigParser::getChatId() { + return ""; +} diff --git a/src/IPRefresher.cpp b/src/IPRefresher.cpp index 230cf86..2744a19 100644 --- a/src/IPRefresher.cpp +++ b/src/IPRefresher.cpp @@ -3,13 +3,13 @@ #include "api/IPAPI.h" #include "api/DynuAPI.h" #include "api/TelegramAPI.h" -#include "Config.h" #include "StaticData.h" #include "IpHelper.h" #include #include #include +#include bool IPRefresher::checkIPAdress(bool force) { FileLogger logger; @@ -35,13 +35,13 @@ bool IPRefresher::checkIPAdress(bool force) { Logger::message("ip changed! -- from :" + oldip + "to: " + ip); DynuAPI dynu; - dynu.init(Config::getDynuapikey(), Config::getDomainid(), Config::getDomainname()); + dynu.init(ConfigParser::getDynuapikey(), ConfigParser::getDomainid(), ConfigParser::getDomainname()); // actual refresh of IP in api - here bool result = dynu.refreshIp(ip); - if (result && Config::isTelegramSupported()) { + if (result && ConfigParser::isTelegramSupported()) { TelegramAPI tele; - tele.init(Config::getTelegramApiKey(), Config::getChatId()); + tele.init(ConfigParser::getTelegramApiKey(), ConfigParser::getChatId()); tele.sendMessage(oldip + " moved to " + ip); } else if (!result) { //error @@ -61,7 +61,7 @@ void IPRefresher::startUpService(int interval) { while (true) { Logger::message("starting check"); - if (Config::readConfig()) { + if (ConfigParser::loadConfig()) { checkIPAdress(false); } else { std::cout << "incorrect credentials!" << std::endl; diff --git a/src/main.cpp b/src/main.cpp index 8e55acd..52035a3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,8 +1,8 @@ #include "StaticData.h" #include "IPRefresher.h" #include "Logger.h" -#include "Config.h" #include "api/IPAPI.h" +#include "ConfigParser.h" /** * application entry point @@ -21,7 +21,7 @@ int main(int argc, char *argv[]) { } else if (firstarg == "-v" || firstarg == "--version") { std::cout << "Version " << StaticData::VERSION << std::endl; } else if (firstarg == "-f" || firstarg == "--force") { - if (Config::readConfig()) { + if (ConfigParser::loadConfig()) { IPRefresher::checkIPAdress(true); } else { std::cout << "incorrect credentials!" << std::endl; @@ -30,7 +30,7 @@ int main(int argc, char *argv[]) { } else if (firstarg == "-l" || firstarg == "--loop") { IPRefresher::startUpService(true); } else if (firstarg == "-c" || firstarg == "--checkconfig") { - if (Config::validateConfig()) { + if (ConfigParser::validateConfig()) { Logger::message("Config file is OK"); } else { Logger::error("There are errors in config file!"); @@ -43,8 +43,11 @@ int main(int argc, char *argv[]) { Logger::message("wrong arguments! -h for help"); } } else { + ConfigParser::loadConfig(); + + return 0; Logger::message("starting check"); - if (Config::readConfig()) { + if (ConfigParser::loadConfig()) { IPRefresher::checkIPAdress(false); } else { std::cout << "incorrect credentials!" << std::endl;