From 860d8c023b82eeca9833d4a3f534c6d11a9523f3 Mon Sep 17 00:00:00 2001 From: Mika Laitio Date: Fri, 3 Aug 2012 18:41:41 +0300 Subject: [PATCH] api fixes and cleanups cleaned up the configuration data file handling via libuci. Signed-off-by: Mika Laitio --- .cproject | 1055 +++++++------------------------ .settings/language.settings.xml | 15 + src/DataReader.cc | 20 +- src/DataReader.hh | 2 +- src/DataSummary.cc | 76 +++ src/DataSummary.hh | 32 + src/Device.cc | 8 +- src/DeviceConfig.cc | 319 ++++------ src/DeviceConfig.hh | 20 +- src/FileUtil.cc | 176 +++++- src/FileUtil.hh | 11 +- src/Makefile.am | 5 +- src/StoreCache.cc | 9 +- src/StoreDay.cc | 2 +- src/config.c | 216 +++---- src/config.h | 18 +- src/private/uci_config.c | 217 +++++++ src/private/uci_config.h | 54 ++ src/str_util.c | 27 + src/str_util.h | 10 + src_test/Makefile.am | 12 +- src_test/test_config.c | 46 -- src_test/test_config1.c | 92 +++ src_test/test_config2.c | 202 ------ src_test/test_config2.cc | 71 +++ 25 files changed, 1248 insertions(+), 1467 deletions(-) create mode 100644 .settings/language.settings.xml create mode 100644 src/DataSummary.cc create mode 100644 src/DataSummary.hh create mode 100644 src/private/uci_config.c create mode 100644 src/private/uci_config.h delete mode 100644 src_test/test_config.c create mode 100644 src_test/test_config1.c delete mode 100644 src_test/test_config2.c create mode 100644 src_test/test_config2.cc diff --git a/.cproject b/.cproject index 8ca237c..2fdfaa9 100644 --- a/.cproject +++ b/.cproject @@ -46,421 +46,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -506,425 +91,235 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml new file mode 100644 index 0000000..8766d20 --- /dev/null +++ b/.settings/language.settings.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/DataReader.cc b/src/DataReader.cc index 00f861a..00fc1f4 100644 --- a/src/DataReader.cc +++ b/src/DataReader.cc @@ -35,12 +35,13 @@ DataReader::DataReader(string device_id_param) { string base_dir; log_debug("device_id: %s\n", device_id_param.c_str()); - device_config = NULL; - device_id = device_id_param; - base_dir = DeviceConfig::get_base_dir_name(); - device_dir = FileUtil::concat_paths(base_dir, device_id); - device_ch_dir = FileUtil::concat_paths(base_dir, "cache"); - device_ch_dir = FileUtil::concat_paths(device_ch_dir, device_id); + summary_calc_type = MEAN; + device_config = NULL; + device_id = device_id_param; + base_dir = DeviceConfig::get_base_dir_name(); + device_dir = FileUtil::concat_paths(base_dir, device_id); + device_ch_dir = FileUtil::concat_paths(base_dir, "cache"); + device_ch_dir = FileUtil::concat_paths(device_ch_dir, device_id); } DataReader::~DataReader() { @@ -447,14 +448,15 @@ string DataReader::get_device_id() { * @rerurn string representing device type. * In the case of error, an empty string is returned. */ -string DataReader::get_device_type() { - string ret_val; +bool DataReader::get_device_type(string& type_param) { + bool ret_val; + ret_val = false; if (device_config == NULL) { device_config = DeviceConfig::get_device_config(device_id); } if (device_config != NULL) { - ret_val = device_config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE); + ret_val = device_config->get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, type_param); } return ret_val; } diff --git a/src/DataReader.hh b/src/DataReader.hh index 23a39d3..b544242 100644 --- a/src/DataReader.hh +++ b/src/DataReader.hh @@ -60,7 +60,7 @@ namespace plp { DataRange *get_data(Date *start_date, Date *end_date); std::string get_device_id(); - std::string get_device_type(); + bool get_device_type(std::string& type_param); Data *get_latest_data(); protected: std::string device_id; diff --git a/src/DataSummary.cc b/src/DataSummary.cc new file mode 100644 index 0000000..5c91ba1 --- /dev/null +++ b/src/DataSummary.cc @@ -0,0 +1,76 @@ +/* + * DataSummary.cc + * + * Created on: Aug 3, 2012 + * Author: lamikr + */ + +#include "DataSummary.hh" + +DataSummary::DataSummary() +{ + // TODO Auto-generated constructor stub + +} + +DataSummary::~DataSummary() +{ + // TODO Auto-generated destructor stub +} + +string DataSummary::get_summary_period_name(enum EnumSummaryPeriod period_param) { + string ret_val; + + switch(period_param) { + case PERIOD_YEARLY: + ret_val = "yearly"; + break; + case PERIOD_MONTHLY: + ret_val = "monthly"; + break; + case PERIOD_DAILY: + ret_val = "daily"; + break; + case PERIOD_HOURLY: + ret_val = "hourly"; + break; + case PERIOD_MINUTELY: + ret_val = "minutely"; + break; + case PERIOD_SECONDLY: + ret_val = "secondly"; + break; + default: + ret_val = "daily"; + break; + } + return ret_val; + +} + +string DataSummary::get_summary_calculation_name(enum EnumSummaryCalculationType type_param) { + string ret_val; + + switch(type_param) { + case SUM: + ret_val = "sum"; + break; + case DELTA: + ret_val = "delta"; + break; + case MIN: + ret_val = "min"; + break; + case MAX: + ret_val = "max"; + break; + case MEAN: + ret_val = "mean"; + break; + default: + ret_val = "sum"; + break; + } + return ret_val; +} + diff --git a/src/DataSummary.hh b/src/DataSummary.hh new file mode 100644 index 0000000..3b08761 --- /dev/null +++ b/src/DataSummary.hh @@ -0,0 +1,32 @@ +/* + * DataSummary.hh + * + * Created on: Aug 3, 2012 + * Author: lamikr + */ + +#ifndef DATASUMMARY_HH_ +#define DATASUMMARY_HH_ + +#include + +extern "C" { + #include + #include +} + +using namespace std; + +enum EnumSummaryPeriod{PERIOD_YEARLY, PERIOD_MONTHLY, PERIOD_DAILY, PERIOD_HOURLY, PERIOD_MINUTELY, PERIOD_SECONDLY}; +enum EnumSummaryCalculationType {SUM, DELTA, MIN, MAX, MEAN}; + +class DataSummary { + public: + DataSummary(); + virtual ~DataSummary(); + std::string device_id; + static std::string get_summary_period_name(enum EnumSummaryPeriod period_param); + static std::string get_summary_calculation_name(enum EnumSummaryCalculationType type_param); +}; + +#endif /* DATASUMMARY_HH_ */ diff --git a/src/Device.cc b/src/Device.cc index d583f16..714e830 100644 --- a/src/Device.cc +++ b/src/Device.cc @@ -11,13 +11,17 @@ using namespace std; using namespace plp; -Device::Device(string id_param, string type_param) { +Device::Device(string id_param, + string type_param) { id = id_param; type = type_param; lifecycle_status = LIFECYCLE_STATUS__UNAVAILABLE; } -Device::Device(std::string id_param, std::string type_param, std::string name_param, plp::EnumDeviceLifeCycleStatus status_param) { +Device::Device(std::string id_param, + string type_param, + string name_param, + plp::EnumDeviceLifeCycleStatus status_param) { id = id_param; type = type_param; name = name_param; diff --git a/src/DeviceConfig.cc b/src/DeviceConfig.cc index 66fe863..75af9f3 100644 --- a/src/DeviceConfig.cc +++ b/src/DeviceConfig.cc @@ -10,11 +10,13 @@ #include #include -#include "log.h" - #include "DataReader.hh" #include "FileUtil.hh" +#include "log.h" +#include "config.h" +#include "private/uci_config.h" + using namespace std; using namespace plp; @@ -38,144 +40,16 @@ ConfigHandle::~ConfigHandle() { free(full_fname); } -static int uci_create_named_section(ConfigHandle *cfg_handle, - const char *section_type, - const char *section_name, - bool save_immediately) -{ - struct uci_ptr ptr; - int ret_val; - char *cmd_dta; - int len; - - ret_val = -1; - if ((cfg_handle != NULL) && - (cfg_handle->_ctx != NULL) && - (cfg_handle->short_fname != NULL) && - (cfg_handle->full_fname != NULL) && - (section_type != NULL) && - (section_name != NULL)) { - len = strlen(cfg_handle->short_fname); - len = len + 1; - len = len + strlen(section_type); - len = len + 1; - len = len + strlen(section_name); - len = len + 1; - cmd_dta = (char *)malloc(len); - if (cmd_dta != NULL) { - snprintf(cmd_dta, - len, - "%s.%s=%s", - cfg_handle->short_fname, - section_name, - section_type); - if (uci_lookup_ptr(cfg_handle->_ctx, &ptr, cmd_dta, true) == UCI_OK) { - ret_val = uci_set(cfg_handle->_ctx, &ptr); - if (ret_val == UCI_OK) { - if (save_immediately) { - ret_val = uci_save(cfg_handle->_ctx, ptr.p); - } - } - } - free(cmd_dta); - } - } - return ret_val; -} - -static bool set_config_value_to_section(ConfigHandle *cfg_handle, - const char *section_type, - const char *section_name, - const char *key, - const char *value) { - struct uci_section *sct; - struct uci_section *tmp_sct; - int err_flg; - struct uci_element *elem; - struct uci_ptr ptr; - bool ret_val; - - ret_val = false; - err_flg = UCI_OK; - if ((cfg_handle != NULL) && - (cfg_handle->_ctx != NULL) && - (cfg_handle->_pkg != NULL) && - (section_type != NULL) && - (section_name != NULL) && - (key != NULL) && - (value != NULL)) { - sct = NULL; - uci_foreach_element(&cfg_handle->_pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - if (sct == NULL) { - log_debug("Creating new section %s to configuration file: %s\n", section_name, cfg_handle->full_fname); - //err_flg = uci_add_named_section(ctx, pkg, section_type, section_name, &sct); - //err_flg = uci_add_section(ctx, pkg, section_name, &sct); - err_flg = uci_create_named_section(cfg_handle, - section_type, - section_name, - false); - if (err_flg == UCI_OK) { - uci_foreach_element(&cfg_handle->_pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - } - } - if (err_flg == UCI_OK) { - memset(&ptr, 0, sizeof(ptr)); - ptr.package = cfg_handle->_pkg->e.name; - ptr.section = sct->e.name; - ptr.option = key; - err_flg = uci_lookup_ptr(cfg_handle->_ctx, &ptr, NULL, false); - if (err_flg == UCI_OK) { - ptr.value = value; - err_flg = uci_set(cfg_handle->_ctx, &ptr); - if (err_flg == UCI_OK) { - err_flg = uci_save(cfg_handle->_ctx, cfg_handle->_pkg); - if (err_flg == UCI_OK) { - ret_val = true; - log_debug("Set value to section %s in configuration file: %s\n", section_name, cfg_handle->full_fname); - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not save the file\n", cfg_handle->full_fname); - } - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not set new value\n", cfg_handle->full_fname); - } - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not look-up pointer for package %s section %s.\n", - cfg_handle->full_fname, - cfg_handle->_pkg->e.name, - sct->e.name); - } - uci_free_context(cfg_handle->_ctx); - } - else { - log_error("Failed to set value to configuration file: %s. Could not create section %s.\n", cfg_handle->full_fname, section_name); - } - } - else { - log_error("Failed to set value to configuration file, invalid parameters\n"); - } - return ret_val; -} - DeviceConfig::DeviceConfig(string device_id_param) { + bool succ; + device_id = device_id_param; uci_handle = load_device_config(device_id_param); if (uci_handle != NULL) { - device_type = get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE); + succ = get_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, device_type); + if (succ == false) { + log_error("Could not read device type from the configuration file.\n"); + } } else { log_error("Could not read device configuration.\n"); @@ -183,7 +57,14 @@ DeviceConfig::DeviceConfig(string device_id_param) { } DeviceConfig::~DeviceConfig() { + bool suc; + if (uci_handle != NULL) { + suc = uci_save_config_values(uci_handle->_ctx, + uci_handle->_pkg); + if (suc == true) { + log_debug("saved the configuration file: %s\n", uci_handle->full_fname); + } delete(uci_handle); uci_handle = NULL; } @@ -215,130 +96,154 @@ string DeviceConfig::get_base_dir_name() { return store_base_dir; } -string DeviceConfig::get_dir_name(string device_id_param) { +string DeviceConfig::get_config_path_name() { string ret_val; - string d_name; + string path_name; - d_name = DeviceConfig::get_base_dir_name(); - ret_val = FileUtil::concat_paths(d_name, device_id_param); + path_name = DeviceConfig::get_base_dir_name(); + ret_val = FileUtil::concat_paths(path_name, device_id); return ret_val; } -string DeviceConfig::get_file_name(string device_id_param) { +string DeviceConfig::get_config_file_name() { string ret_val; - string fname; + string fname_base; - fname = DEVICE_CONFIG__FILE_NAME; - ret_val = get_dir_name(device_id_param); - ret_val = FileUtil::concat_paths(ret_val, fname); + fname_base = DEVICE_CONFIG__FILE_NAME; + ret_val = get_config_path_name(); + ret_val = FileUtil::concat_paths(ret_val, fname_base); return ret_val; } -string DeviceConfig::get_config_value(string key) { - struct uci_section *section; - struct uci_option *option; - string ret_val; +string DeviceConfig::get_pathless_config_file_name() { + return DEVICE_CONFIG__FILE_NAME; +} - if (uci_handle != NULL) { - section = uci_lookup_section(uci_handle->_ctx, - uci_handle->_pkg, - DEVICE_CONFIG__SECTION_NAME); - if (section != NULL) { - option = uci_lookup_option(uci_handle->_ctx, section, key.c_str()); - if (option != NULL) { - switch (option->type) { - case UCI_TYPE_STRING: - //log_info("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string); - ret_val = option->v.string; - break; - default: - log_error("key: %s Failed to read parameter value\n", key.c_str()); - break; - } - } - else { - log_error("key: %s Failed to read parameter value\n", key.c_str()); +bool DeviceConfig::get_config_value(string key, string& value) { + char *ret; + bool ret_val; + + ret_val = false; + value.clear(); + if ((uci_handle != NULL) && + (uci_handle->_ctx != NULL) && + (uci_handle->_pkg != NULL)) { + if (key.empty() == false) { + ret = uci_get_config_value(uci_handle->_ctx, + uci_handle->_pkg, + DEVICE_CONFIG__SECTION_NAME, + key.c_str()); + if (ret != NULL) { + ret_val = true; + value = ret; } } + else { + log_error("Failed to read configuration value, key was empty string.\n"); + } + } + else { + log_error("Failed to read configuration value for key: %s. Invalid handle to configuration file.\n", key.c_str()); } return ret_val; } -void DeviceConfig::set_config_value(string key, - string value) { +bool DeviceConfig::set_config_value(string key, + string value, + bool save_immediately) { string cfg_dir; string cfg_fl; + bool ret_val; - cfg_dir = get_dir_name(device_id); + cfg_dir = get_config_path_name(); cfg_fl = DEVICE_CONFIG__FILE_NAME; - set_config_value_to_section(uci_handle, - DEVICE_CONFIG__SECTION_TYPE, - DEVICE_CONFIG__SECTION_NAME, - key.c_str(), - value.c_str()); + if (uci_handle != NULL) { + if ((uci_handle->_ctx != NULL) && + (uci_handle->_pkg != NULL) && + (uci_handle->short_fname != NULL) && + (uci_handle->full_fname != NULL)) { + //log_debug("uci_handle != null, short_name: %s, full_name: %s\n", + // uci_handle->short_fname, uci_handle->full_fname); + //log_debug("key: %s, value: %s\n", key.c_str(), value.c_str()); + ret_val = uci_set_config_value(uci_handle->_ctx, + uci_handle->_pkg, + uci_handle->short_fname, + uci_handle->full_fname, + DEVICE_CONFIG__SECTION_TYPE, + DEVICE_CONFIG__SECTION_NAME, + key.c_str(), + value.c_str(), + save_immediately); + } + else { + log_error("Could not set config value for device %s: key: %s, value: %s. Invalid filename in handle.\n", + device_id.c_str(), key.c_str(), value.c_str()); + } + } + else { + log_error("Could not set config value for device %s: key: %s, value: %s. Invalid handle to config file\n", + device_id.c_str(), key.c_str(), value.c_str()); + } + return ret_val; } +// TODO: This function should be moved else where or it should be dynamic... EnumSummaryCalculationType DeviceConfig::get_summary_calculation_type() { - EnumSummaryCalculationType ret_val; - - ret_val = MEAN; if (device_type.empty() == false) { if (device_type.compare("Counter Device") == 0) { - ret_val = DELTA; + return DELTA; } } - return ret_val;; + return MEAN; } ConfigHandle *DeviceConfig::load_device_config(string device_id_param) { int err_flg; struct uci_context *ctx; struct uci_package *pkg; - string cfg_fl; + string fname_base; + string fname_full; string cfg_dir; - int b_count; - char *fname; ConfigHandle *ret_val; + FILE *fp; ret_val = NULL; - cfg_dir = get_dir_name(device_id_param); + cfg_dir = get_config_path_name(); if (cfg_dir.empty() == false) { - if (access(cfg_dir.c_str(), W_OK) != 0) { - FileUtil::mkdirs(cfg_dir.c_str()); - } - cfg_fl = get_file_name(device_id_param); - if (access(cfg_fl.c_str(), R_OK) == 0) { + fname_full = get_config_file_name(); + if (FileUtil::file_exist(fname_full.c_str(), false) == false) + FileUtil::mkfile(fname_full.c_str(), false); + if (access(fname_full.c_str(), R_OK) == 0) { ctx = uci_alloc_context(); if (ctx != NULL) { - log_debug("confdir: %s, file: %s\n", cfg_dir.c_str(), cfg_fl.c_str()); + log_debug("configuration file: %s\n", fname_full.c_str()); uci_set_confdir(ctx, cfg_dir.c_str()); - err_flg = uci_load(ctx, cfg_fl.c_str(), &pkg); + err_flg = uci_load(ctx, fname_full.c_str(), &pkg); if (err_flg == UCI_OK) { //log_debug("Loaded device configuration: %s.\n", cfg_fl.c_str()); - b_count = strlen(cfg_dir.c_str()) + strlen(cfg_fl.c_str()) + 10; - fname = (char *)calloc(1, b_count); - if (fname != NULL) { - strncpy(fname, cfg_dir.c_str(), b_count); - strncat(fname, "/", 1); - strncat(fname, cfg_fl.c_str(), strlen(cfg_fl.c_str()) + 1); - - ret_val = new ConfigHandle(ctx, pkg, cfg_fl.c_str(), fname); - free(fname); - } + fname_base = get_pathless_config_file_name(); + ret_val = new ConfigHandle(ctx, + pkg, + fname_base.c_str(), + fname_full.c_str()); } else { - log_debug("Failed to load device configuration: %s, err code: %d.\n", cfg_fl.c_str(), UCI_OK); - set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, ""); - uci_free_context(ctx); + log_debug("Failed to load device configuration: %s, err code: %d.\n", fname_full.c_str(), UCI_OK); + fp = fopen(fname_full.c_str(), "w+"); + if (fp != NULL) + fclose(fp); + //uci_free_context(ctx); } } else { log_error("Failed to load device configuration, memory allocation error.\n"); - set_config_value(DEVICE_CONFIG_VALUE_KEY__TYPE, ""); + fp = fopen(fname_full.c_str(), "w+"); + if (fp != NULL) + fclose(fp); } } else { - log_error("Failed to load device configuration, file does not exist: %s.\n", cfg_fl.c_str()); + log_error("Failed to load device configuration, file does not exist: %s.\n", fname_full.c_str()); } } return ret_val; diff --git a/src/DeviceConfig.hh b/src/DeviceConfig.hh index 0ede135..52f2db8 100644 --- a/src/DeviceConfig.hh +++ b/src/DeviceConfig.hh @@ -9,18 +9,13 @@ #define DEVICECONFIG_HH_ #include +#include "DataSummary.hh" extern "C" { #include #include } -enum EnumSummaryPeriod{PERIOD_YEARLY, PERIOD_MONTHLY, PERIOD_DAILY, PERIOD_HOURLY, PERIOD_MINUTELY, PERIOD_SECONDLY}; -enum EnumSummaryCalculationType {SUM, DELTA, MIN, MAX, MEAN}; - -const std::string SUMMARY_PERIOD_NAMES_ARRAY[] = {"yearly", "monthly", "daily", "minutely", "secondly"}; -const std::string CALCULATION_TYPE_NAMES_ARRAY[] = {"sum", "delta", "min", "max", "mean"}; - #define DEVICE_CONFIG__FILE_NAME "device_cfg" #define DEVICE_CONFIG__SECTION_TYPE "device" #define DEVICE_CONFIG__SECTION_NAME "base_data" @@ -55,9 +50,13 @@ namespace plp { static long get_read_interval_seconds(); static void set_read_interval_seconds(long seconds_param); static DeviceConfig *get_device_config(std::string device_id); - std::string get_config_value(std::string key); - void set_config_value(std::string key, - std::string value); + bool get_config_value(std::string key, std::string& value); + bool set_config_value(std::string key, + std::string value, + bool save_immediately); + std::string get_config_path_name(); + std::string get_config_file_name(); + std::string get_pathless_config_file_name(); EnumSummaryCalculationType get_summary_calculation_type(); private: static std::string store_base_dir; @@ -66,8 +65,7 @@ namespace plp { std::string device_type; ConfigHandle *uci_handle; ConfigHandle *load_device_config(std::string device_id_param); - std::string get_dir_name(std::string device_id); - std::string get_file_name(std::string device_id_param); + }; } diff --git a/src/FileUtil.cc b/src/FileUtil.cc index 0b97ff9..1a45e89 100644 --- a/src/FileUtil.cc +++ b/src/FileUtil.cc @@ -38,27 +38,36 @@ FileUtil::FileUtil() { FileUtil::~FileUtil() { } -char *FileUtil::parse_directory_path(const char *file_path) { +/* + * Parses directory path from the full filename and + * returns it's copy. + */ +string FileUtil::parse_directory_path(const char *file_name_with_path) { char *p; size_t b_count; size_t f_size; - char *ret_val; + char *ret; + string ret_val; - ret_val = NULL; - if (file_path != NULL) { + ret = NULL; + if (file_name_with_path != NULL) { f_size = 0; - b_count = strlen(file_path); - for (p = &((char *)file_path)[b_count]; p != (char *)file_path; p--) { + b_count = strlen(file_name_with_path); + for (p = &((char *)file_name_with_path)[b_count]; p != (char *)file_name_with_path; p--) { f_size++; if ((*p == '/') || (*p == '\\')) { b_count = (b_count - f_size) + 1; - ret_val = strndup(file_path, b_count); - log_debug("dir: %s\n", ret_val); + ret = strndup(file_name_with_path, b_count); + //log_debug("path ret_val: %s\n", ret); break; } } } + if (ret != NULL) { + ret_val = ret; + free(ret); + } return ret_val; } @@ -69,12 +78,28 @@ bool FileUtil::mkdirs(const char *path) { ret_val = true; if (path != NULL) { - // go through each directory one by and and create if not exist - for (p = (char *)path; *p; p++) { - if ((p != path) && - ((*p == '/') || - (*p == '\\'))) { - *p = '\0'; + if (access(path, F_OK) != 0) { + // path does not exist, need to create it + // go through each directory one by one and create them if they do not yet exist + for (p = (char *)path; *p; p++) { + if ((p != path) && + ((*p == '/') || + (*p == '\\'))) { + *p = '\0'; + // if dir does not exist, create it + if (access(path, F_OK) != 0) { + //log_debug("trying to create directory: %s\n", path); + err_flg = mkdir(path, S_IRWXU); + if (err_flg != 0) { + log_error("Could not create directory: %s\n", path); + ret_val = false; + break; + } + } + *p = '/'; + } + } + if (ret_val == true) { // if dir does not exist, create it if (access(path, F_OK) != 0) { //log_debug("trying to create directory: %s\n", path); @@ -82,22 +107,12 @@ bool FileUtil::mkdirs(const char *path) { if (err_flg != 0) { log_error("Could not create directory: %s\n", path); ret_val = false; - break; } } - *p = '/'; } } - if (ret_val == true) { - // if dir does not exist, create it - if (access(path, F_OK) != 0) { - //log_debug("trying to create directory: %s\n", path); - err_flg = mkdir(path, S_IRWXU); - if (err_flg != 0) { - log_error("Could not create directory: %s\n", path); - ret_val = false; - } - } + else { + ret_val = true; } } else { @@ -107,8 +122,108 @@ bool FileUtil::mkdirs(const char *path) { return ret_val; } +bool FileUtil::file_exist(const char *file_name_with_path, bool writable) { + bool ret_val; + int acl_mode; + + ret_val = false; + if (writable == true) { + acl_mode = W_OK; + } + else { + acl_mode = R_OK; + } + if (file_name_with_path != NULL) { + if (access(file_name_with_path, acl_mode) == 0) { + ret_val = true; + } + } + return ret_val; +} + +bool FileUtil::mkfile(const char *file_name_with_path, bool writable) { + bool ret_val; + string path_name; + const char *acl; + int acl_mode; + FILE *fp; + bool succ_bool; + + ret_val = false; + acl = "a"; + if (writable == true) { + acl_mode = W_OK; + } + else { + acl_mode = R_OK; + } + if (file_name_with_path != NULL) { + if (access(file_name_with_path, F_OK) != 0) { + // file does not exist, create it + path_name = parse_directory_path(file_name_with_path); + succ_bool = true; + if (access(path_name.c_str(), F_OK) != 0) { + // path to file does not exist, create it + succ_bool = mkdirs(path_name.c_str()); + } + if (succ_bool == true) { + // create file with read or write acl rights + fp = fopen(file_name_with_path, acl); + if (fp != NULL) { + ret_val = true; + fclose(fp); + } + } + } + else { + // file already exist, check access rights and change if needed + ret_val = true; + if (access(file_name_with_path, acl_mode) != 0) { + // file does not have specified acl righs, try to grant them + fp = fopen(file_name_with_path, acl); + if (fp != NULL) { + ret_val = true; + fclose(fp); + } + } + } + } + return ret_val; + +/* + path_name = parse_directory_path(file_name_with_path) + if (cfg_dir.empty() == false) { + if (access(path_name.c_str(), F_OK) != 0) { + // config dir does not exist, create it + FileUtil::mkdirs(cfg_dir.c_str()); + } + if (access(cfg_dir.c_str(), R_OK) != 0) { + // config dir does not have read access, add it + fp = fopen(cfg_dir.c_str(), "r+"); + if (fp != NULL) + fclose(fp); + } + fname_full = get_config_file_name(); + if (access(fname_full.c_str(), F_OK) != 0) { + // config file does not exist, create empty one + fp = fopen(fname_full.c_str(), "w+"); + if (fp != NULL) + fclose(fp); + } + if (access(fname_full.c_str(), R_OK) != 0) { + // config file does not have read access, add it + fp = fopen(fname_full.c_str(), "r+"); + if (fp != NULL) + fclose(fp); + } + if (access(fname_full.c_str(), R_OK) == 0) { + + } +*/ +} + std::ofstream *FileUtil::open_for_writing(const char *f_path) { - char *d_path; + string path_name; size_t b_count; ofstream *ret_val; bool b_flg; @@ -122,10 +237,9 @@ std::ofstream *FileUtil::open_for_writing(const char *f_path) { ret_val = new ofstream(); ret_val->open(f_path, ios::app); if (ret_val->is_open() == false) { - d_path = parse_directory_path(f_path); - if (d_path != NULL) { - b_flg = mkdirs(d_path); - free(d_path); + path_name = parse_directory_path(f_path); + if (path_name.empty() == false) { + b_flg = mkdirs(path_name.c_str()); } if (b_flg == true) { ret_val->open(f_path, ios::app); diff --git a/src/FileUtil.hh b/src/FileUtil.hh index e69ada8..50b3ddd 100644 --- a/src/FileUtil.hh +++ b/src/FileUtil.hh @@ -24,8 +24,17 @@ namespace plp { static bool is_datafile(const char *path, dirent *direntry); static std::vector get_subdirectories(const std::string& path); static std::vector get_data_files(const std::string& path); - static char *parse_directory_path(const char *file_path); + static std::string parse_directory_path(const char *file_name_with_path); static bool mkdirs(const char *path); + /* + * Creates file to given path by first checking whether + * the directories exist and have enough permissions. + */ + static bool mkfile(const char *file_name_with_path, bool writable); + /* + * Check whether file exist with specified access rights + */ + static bool file_exist(const char *file_name_with_path, bool writable); static std::ofstream *open_for_writing(const char *path); }; } diff --git a/src/Makefile.am b/src/Makefile.am index b815100..58153f8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,6 +2,7 @@ lib_LTLIBRARIES = libplp.la libplp_la_SOURCES = \ config.c config.h \ Data.hh Data.cc \ + DataSummary.hh DataSummary.cc \ DataReader.hh DataReader.cc \ Date.hh Date.cc \ Device.hh Device.cc \ @@ -16,7 +17,8 @@ libplp_la_SOURCES = \ log.h \ log_config.c \ str_util.c str_util.h \ - retval.h + retval.h \ + private/uci_config.c private/uci_config.h libplp_la_LDFLAGS = $(SRC_LIBS) $(all_libraries) -version-info 1:0:0 -no-undefined AM_CPPFLAGS = $(SRC_CFLAGS) DISTCLEANFILES = Makefile.in @@ -27,6 +29,7 @@ libplpinclude_HEADERS = \ retval.h \ str_util.h \ Data.hh \ + DataSummary.hh \ DataReader.hh \ Date.hh \ Device.hh \ diff --git a/src/StoreCache.cc b/src/StoreCache.cc index 3506292..0d62d77 100644 --- a/src/StoreCache.cc +++ b/src/StoreCache.cc @@ -31,12 +31,17 @@ string StoreCache::get_dir_name(string device_id_param, string ret_val; char buffer[30]; string bd_name; + string period_name; + string calc_type; + + period_name = DataSummary::get_summary_period_name(period_type_param); + calc_type = DataSummary::get_summary_calculation_name(calc_type_param); bd_name = DeviceConfig::get_base_dir_name(); bd_name = FileUtil::concat_paths(bd_name, CACHE_DIR_NAME); bd_name = FileUtil::concat_paths(bd_name, device_id_param); - bd_name = FileUtil::concat_paths(bd_name, SUMMARY_PERIOD_NAMES_ARRAY[period_type_param]); - bd_name = FileUtil::concat_paths(bd_name, CALCULATION_TYPE_NAMES_ARRAY[calc_type_param]); + bd_name = FileUtil::concat_paths(bd_name, period_name); + bd_name = FileUtil::concat_paths(bd_name, calc_type); if (period_type_param == PERIOD_YEARLY) { ret_val = bd_name; } diff --git a/src/StoreDay.cc b/src/StoreDay.cc index a29c6a0..5d71b37 100644 --- a/src/StoreDay.cc +++ b/src/StoreDay.cc @@ -83,7 +83,7 @@ void StoreDay::save(string device_id, /* needs to be casted to long unsigned int value is "unsigned int" in some toolchains and that would otherwise cause an warning/error */ - log_info("[%s] writing %lu data values to save.\n", device_id.c_str(), + log_info("[%s] saving %lu data values.\n", device_id.c_str(), (long unsigned int)data_list->size()); // TODO: add mutex to protect string_list while it's read and emptied for(iter = data_list->begin(); iter != data_list->end(); iter++) { diff --git a/src/config.c b/src/config.c index 32f0a93..9c479a0 100644 --- a/src/config.c +++ b/src/config.c @@ -4,158 +4,150 @@ #include #include +#include "private/uci_config.h" #include "config.h" #include "log.h" -static int uci_create_named_section(struct uci_context *ctx, - const char *conf_file_name, - const char *section_type, - const char *section_name) -{ - struct uci_ptr ptr; - int ret_val; - char *cmd_data; - int len; - - ret_val = -1; - if ((ctx != NULL) && - (conf_file_name != NULL) && - (section_type != NULL) && - (section_name != NULL)) { - len = strlen(conf_file_name); - len = len + 1; - len = len + strlen(section_type); - len = len + 1; - len = len + strlen(section_name); - len = len + 1; - cmd_data = malloc(len); - if (cmd_data != NULL) { - snprintf(cmd_data, len, "%s.%s=%s", conf_file_name, section_name, section_type); - if (uci_lookup_ptr(ctx, &ptr, cmd_data, true) == UCI_OK) { - ret_val = uci_set(ctx, &ptr); - if (ret_val == UCI_OK) { - ret_val = uci_save(ctx, ptr.p); - } - } - free(cmd_data); - } - } - return ret_val; -} - -bool set_config_value_to_section(const char *conf_dir_name, - const char *conf_file_name, +bool set_config_value_and_save(const char *conf_dir_name, + const char *conf_file_basename, const char *section_type, const char *section_name, const char *key, const char *value) { struct uci_context *ctx; struct uci_package *pkg; - struct uci_section *sct; - struct uci_section *tmp_sct; int err_flg; - char *fname; + char *conf_fname_full; int b_count; - struct uci_element *elem; - struct uci_ptr ptr; FILE *fp; bool ret_val; ret_val = false; + pkg = NULL; if ((conf_dir_name != NULL) && - (conf_file_name != NULL) && + (conf_file_basename != NULL) && (section_type != NULL) && (section_name != NULL) && (key != NULL) && (value != NULL)) { - b_count = strlen(conf_dir_name) + strlen(conf_file_name) + 10; - fname = (char *)calloc(1, b_count); - if (fname != NULL) { - strncpy(fname, conf_dir_name, b_count); - strncat(fname, "/", 1); - strncat(fname, conf_file_name, strlen(conf_file_name) + 1); + b_count = strlen(conf_dir_name) + strlen(conf_file_basename) + 10; + conf_fname_full = (char *)calloc(1, b_count); + if (conf_fname_full != NULL) { + strncpy(conf_fname_full, conf_dir_name, b_count); + strncat(conf_fname_full, "/", 1); + strncat(conf_fname_full, conf_file_basename, strlen(conf_file_basename) + 1); ctx = uci_alloc_context(); if (ctx != NULL) { - sct = NULL; - uci_set_confdir(ctx, conf_dir_name); - if (access(fname, W_OK) != 0) { - if (access(fname, F_OK) != 0) { - fp = fopen(fname, "w+"); + if (access(conf_fname_full, W_OK) != 0) { + // if file is not writable, try to change it to be writable + if (access(conf_fname_full, F_OK) != 0) { + fp = fopen(conf_fname_full, "w+"); fclose(fp); } } - if (access(fname, W_OK) == 0) { - err_flg = uci_load(ctx, fname, &pkg); - uci_foreach_element(&pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - if (sct == NULL) { - log_debug("Creating new section %s to configuration file: %s\n", section_name, fname); - //err_flg = uci_add_named_section(ctx, pkg, section_type, section_name, &sct); - //err_flg = uci_add_section(ctx, pkg, section_name, &sct); - err_flg = uci_create_named_section(ctx, - conf_file_name, + if (access(conf_fname_full, W_OK) == 0) { + uci_set_confdir(ctx, + conf_dir_name); + err_flg = uci_load(ctx, conf_fname_full, &pkg); + if ((err_flg == UCI_OK) && + (pkg != NULL)) { + ret_val = uci_set_config_value(ctx, + pkg, + conf_file_basename, + conf_fname_full, section_type, - section_name); - if (err_flg == UCI_OK) { - uci_foreach_element(&pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - } + section_name, + key, + value, + true); } - if (err_flg == UCI_OK) { - memset(&ptr, 0, sizeof(ptr)); - ptr.package = pkg->e.name; - ptr.section = sct->e.name; - ptr.option = key; - err_flg = uci_lookup_ptr(ctx, &ptr, NULL, false); - if (err_flg == UCI_OK) { - ptr.value = value; - err_flg = uci_set(ctx, &ptr); - if (err_flg == UCI_OK) { - err_flg = uci_save(ctx, pkg); - if (err_flg == UCI_OK) { - ret_val = true; - log_debug("Set value to section %s in configuration file: %s\n", section_name, fname); - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not save the file\n", fname); - } + else { + log_error("Failed to set value to configuration file: %s. Could not load current file content.\n", conf_fname_full); + } + } + else { + log_error("Failed to set value to configuration file: %s. File does not exist or is not writable\n", conf_fname_full); + } + //TODO: uci_free_package(pkg) ?, or will uci_free_contect(ctx) also free the package + uci_free_context(ctx); + } + free(conf_fname_full); + } + else { + log_error("Failed to set value to configuration file: %s/%s, out of memory\n", conf_dir_name, conf_file_basename); + } + } + else { + log_error("Failed to set value to configuration file, invalid parameters\n"); + } + return ret_val; +} + +char* get_config_value_and_close(const char *conf_dir_name, + const char *conf_file_basename, + const char *section_name, + const char *key) { + struct uci_context *ctx; + struct uci_package *pkg; + int err_flg; + char *conf_fname_full; + int b_count; + FILE *fp; + char *ret_val; - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not set new value\n", fname); - } - } - else { - log_error("Failed to set value to configuration file: %s\n. Could not look-up pointer for package %s section %s.\n", fname, pkg->e.name, sct->e.name); - } - uci_free_context(ctx); + ret_val = NULL; + pkg = NULL; + if ((conf_dir_name != NULL) && + (conf_file_basename != NULL) && + (section_name != NULL) && + (key != NULL)) { + b_count = strlen(conf_dir_name) + strlen(conf_file_basename) + 10; + conf_fname_full = (char *)calloc(1, b_count); + if (conf_fname_full != NULL) { + strncpy(conf_fname_full, conf_dir_name, b_count); + strncat(conf_fname_full, "/", 1); + strncat(conf_fname_full, conf_file_basename, strlen(conf_file_basename) + 1); + ctx = uci_alloc_context(); + if (ctx != NULL) { + if (access(conf_fname_full, R_OK) != 0) { + // if file is not writable, try to change it to be writable + if (access(conf_fname_full, R_OK) != 0) { + fp = fopen(conf_fname_full, "w+"); + fclose(fp); + } + } + if (access(conf_fname_full, R_OK) == 0) { + uci_set_confdir(ctx, + conf_dir_name); + err_flg = uci_load(ctx, conf_fname_full, &pkg); + if ((err_flg == UCI_OK) && + (pkg != NULL)) { + ret_val = uci_get_config_value(ctx, + pkg, + section_name, + key); + // need to duplicate response val, as uci_free_context() would free the value otherwise + if (ret_val != NULL) + ret_val = strdup(ret_val); } else { - log_error("Failed to set value to configuration file: %s. Could not create section %s.\n", fname, section_name); + log_error("Failed to get value from configuration file: %s. Could not load current file content.\n", conf_fname_full); } } else { - log_error("Failed to set value to configuration file: %s. File does not exist or is not writable\n.", fname); + log_error("Failed to get value from configuration file: %s. File does not exist or is not readable.\n", conf_fname_full); } + //TODO: uci_free_package(pkg) ?, or will uci_free_contect(ctx) also free the package + uci_free_context(ctx); } - free(fname); + free(conf_fname_full); } else { - log_error("Failed to set value to configuration file: %s, out of memory\n", fname); + log_error("Failed to get value from configuration file: %s/%s, out of memory.\n", conf_dir_name, conf_file_basename); } } else { - log_error("Failed to set value to configuration file, invalid parameters\n"); + log_error("Failed to get value from configuration file, invalid parameters.\n"); } return ret_val; } diff --git a/src/config.h b/src/config.h index 378ec3e..69e406d 100644 --- a/src/config.h +++ b/src/config.h @@ -10,14 +10,22 @@ #include -struct uci_context *_ctx; -struct uci_package *_pkg; - -bool set_config_value_to_section(const char *conf_dir_name, - const char *conf_file_name, +#ifdef __cplusplus +extern "C" +#endif +bool set_config_value_and_save(const char *conf_dir_name, + const char *conf_file_basename, const char *section_type, const char *section_name, const char *key, const char *value); +#ifdef __cplusplus +extern "C" +#endif +char* get_config_value_and_close(const char *conf_dir_name, + const char *conf_file_basename, + const char *section_name, + const char *key); + #endif /* CONFIG_H_ */ diff --git a/src/private/uci_config.c b/src/private/uci_config.c new file mode 100644 index 0000000..756f2b7 --- /dev/null +++ b/src/private/uci_config.c @@ -0,0 +1,217 @@ +/* + * uci_config.c + * + * Created on: Aug 2, 2012 + * Author: lamikr + */ + +#include "uci_config.h" +#include "../log.h" + +int uci_create_named_section(struct uci_context *ctx, + const char *conf_fname_base, + const char *section_type, + const char *section_name, + bool save_immediately) +{ + struct uci_ptr ptr; + int ret_val; + char *cmd_data; + int len; + + ret_val = -1; + if ((ctx != NULL) && + (conf_fname_base != NULL) && + (section_type != NULL) && + (section_name != NULL)) { + len = strlen(conf_fname_base); + len = len + 1; + len = len + strlen(section_type); + len = len + 1; + len = len + strlen(section_name); + len = len + 1; + cmd_data = malloc(len); + if (cmd_data != NULL) { + snprintf(cmd_data, + len, + "%s.%s=%s", + conf_fname_base, + section_name, + section_type); + if (uci_lookup_ptr(ctx, &ptr, cmd_data, true) == UCI_OK) { + ret_val = uci_set(ctx, &ptr); + if (ret_val == UCI_OK) { + if (save_immediately) { + ret_val = uci_save(ctx, ptr.p); + } + } + } + free(cmd_data); + } + } + return ret_val; +} + +bool uci_set_config_value(struct uci_context *ctx, + struct uci_package *pkg, + const char *conf_fname_base, + const char *conf_fname_full, + const char *section_type, + const char *section_name, + const char *key, + const char *value, + const bool save_immediately) { + struct uci_section *sct; + struct uci_section *tmp_sct; + int err_flg; + struct uci_element *elem; + struct uci_ptr ptr; + bool ret_val; + + ret_val = false; + err_flg = UCI_OK; + if ((ctx != NULL) && + (pkg != NULL) && + (section_type != NULL) && + (section_name != NULL) && + (key != NULL) && + (value != NULL)) { + sct = NULL; + uci_foreach_element(&pkg->sections, elem) { + tmp_sct = uci_to_section(elem); + if (tmp_sct != NULL) { + if (strcmp(tmp_sct->type, section_type) == 0) { + sct = tmp_sct; + break; + } + else { + //TODO: uci_free_section(tmp_sct); ?, or will uci_free_contect(ctx) also free the section + } + } + } + if (sct == NULL) { + //log_debug("Creating new section %s to configuration file: %s\n", section_name, conf_fname_full); + //err_flg = uci_add_named_section(ctx, pkg, section_type, section_name, &sct); + //err_flg = uci_add_section(ctx, pkg, section_name, &sct); + err_flg = uci_create_named_section(ctx, + conf_fname_base, + section_type, + section_name, + false); + if (err_flg == UCI_OK) { + uci_foreach_element(&pkg->sections, elem) { + tmp_sct = uci_to_section(elem); + if (strcmp(tmp_sct->type, section_type) == 0) { + sct = tmp_sct; + break; + } + } + } + //TODO: uci_free_section(sct); ?, or will uci_free_contect(ctx) also free the section + } + if (err_flg == UCI_OK) { + memset(&ptr, 0, sizeof(ptr)); + ptr.package = pkg->e.name; + ptr.section = sct->e.name; + ptr.option = key; + err_flg = uci_lookup_ptr(ctx, &ptr, NULL, false); + if (err_flg == UCI_OK) { + ptr.value = value; + err_flg = uci_set(ctx, &ptr); + log_debug("file: %s, section_key: %s/%s: value: %s.\n", + conf_fname_full, + section_name, + key, + value); + if (err_flg == UCI_OK) { + if (save_immediately == true) { + err_flg = uci_save(ctx, pkg); + if (err_flg == UCI_OK) { + ret_val = true; + } + else { + log_error("Failed to set value to configuration file: %s. Could not save the file.\n", conf_fname_full); + } + } + else { + ret_val = true; + } + } + else { + log_error("Failed to set value to configuration file: %s. Could not set new value.\n", conf_fname_full); + } + } + else { + log_error("Failed to set value to configuration file: %s. Could not look-up pointer for package %s section %s.\n", + conf_fname_full, + pkg->e.name, + sct->e.name); + } + } + else { + log_error("Failed to set value to configuration file: %s. Could not create section %s.\n", conf_fname_full, section_name); + } + } + else { + log_error("Failed to set value to configuration file, invalid parameters\n"); + } + return ret_val; +} + +char *uci_get_config_value(struct uci_context *ctx, + struct uci_package *pkg, + const char *section_name, + const char *key_name) { + struct uci_section *section; + struct uci_option *option; + char *ret_val; + + ret_val = NULL; + if ((ctx != NULL) && + (pkg != NULL)) { + section = uci_lookup_section(ctx, + pkg, + section_name); + if (section != NULL) { + option = uci_lookup_option(ctx, + section, + key_name); + if (option != NULL) { + switch (option->type) { + case UCI_TYPE_STRING: + //log_debug("key: %s option name: %s, value: %s\n", key.c_str(), option->e.name, option->v.string); + ret_val = option->v.string; + break; + default: + log_error("Failed to read configuration value for key: %s\n", key_name); + break; + } + } + else { + log_error("Failed to find configuration key: %s\n", key_name); + } + } + else { + log_error("Failed to find configuration section name: %s\n", section_name); + } + } + return ret_val; +} + +bool uci_save_config_values(struct uci_context *ctx, + struct uci_package *pkg) { + bool ret_val; + int err_flg; + + if ((ctx != NULL) && + (pkg != NULL)) { + err_flg = uci_save(ctx, pkg); + if (err_flg == UCI_OK) { + ret_val = true; + } + else { + log_error("Could not save configuration file.\n"); + } + } + return ret_val; +} diff --git a/src/private/uci_config.h b/src/private/uci_config.h new file mode 100644 index 0000000..c06e725 --- /dev/null +++ b/src/private/uci_config.h @@ -0,0 +1,54 @@ +/* + * uci_config.h + * + * Created on: Aug 2, 2012 + * Author: lamikr + */ + +#ifndef UCI_CONFIG_H_ +#define UCI_CONFIG_H_ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +#endif +int uci_create_named_section(struct uci_context *ctx, + const char *conf_fname_base, /* filename without directories */ + const char *section_type, + const char *section_name, + bool save_immediately); + +#ifdef __cplusplus +extern "C" +#endif +bool uci_set_config_value(struct uci_context *ctx, + struct uci_package *pkg, + const char *conf_fname_base, + const char *conf_fname_full, + const char *section_type, + const char *section_name, + const char *key, + const char *value, + const bool save_immediately); + +#ifdef __cplusplus +extern "C" +#endif +char *uci_get_config_value(struct uci_context *ctx, + struct uci_package *pkg, + const char *section_name, + const char *key_name); + +#ifdef __cplusplus +extern "C" +#endif +bool uci_save_config_values(struct uci_context *ctx, + struct uci_package *pkg); + +#endif /* UCI_CONFIG_H_ */ diff --git a/src/str_util.c b/src/str_util.c index aca2fd8..abf521b 100644 --- a/src/str_util.c +++ b/src/str_util.c @@ -8,6 +8,10 @@ #include #include #include +#include +#include + +#include char *get_as_hex_str(const char *byte_arr, int byte_count) { int ii; @@ -33,3 +37,26 @@ char *get_as_hex_str(const char *byte_arr, int byte_count) { } return ret_val; } + +bool parse_long(const char *str, long *result) { + int new_result; + char *endptr; + bool ret_val; + + ret_val = false; + errno = 0; + new_result = strtol(str, &endptr, 10); + if (errno != 0) { + log_error("invalid input %s, could not convert to integer.\n", str); + } + else { + if (endptr == str) { + log_error("invalid input %s, could not convert to integer.\n", str); + } + else { + *result = new_result; + ret_val = true; + } + } + return ret_val; +} diff --git a/src/str_util.h b/src/str_util.h index 2a1a599..b73da8a 100644 --- a/src/str_util.h +++ b/src/str_util.h @@ -8,6 +8,16 @@ #ifndef STR_UTIL_H_ #define STR_UTIL_H_ +#include + +#ifdef __cplusplus +extern "C" +#endif char *get_as_hex_str(const char *byte_arr, int byte_count); +#ifdef __cplusplus +extern "C" +#endif +bool parse_long(const char *str, long *result); + #endif /* STR_UTIL_H_ */ diff --git a/src_test/Makefile.am b/src_test/Makefile.am index f8909e6..aca423a 100644 --- a/src_test/Makefile.am +++ b/src_test/Makefile.am @@ -1,15 +1,15 @@ noinst_PROGRAMS = test_logs \ - test_config \ - test_config2 + test_config1_c \ + test_config2_cc test_logs_SOURCES = test_logs.c test_logs_LDADD = $(SRC_LIBS) ../src/.libs/libplp.a -test_config_SOURCES = test_config.c -test_config_LDADD = $(SRC_LIBS) ../src/.libs/libplp.a +test_config1_c_SOURCES = test_config1.c +test_config1_c_LDADD = $(SRC_LIBS) ../src/.libs/libplp.a -test_config2_SOURCES = test_config2.c -test_config2_LDADD = $(SRC_LIBS) ../src/.libs/libplp.a +test_config2_cc_SOURCES = test_config2.cc +test_config2_cc_LDADD = $(SRC_LIBS) ../src/.libs/libplp.a AM_CPPFLAGS = $(SRC_CFLAGS) -I../src diff --git a/src_test/test_config.c b/src_test/test_config.c deleted file mode 100644 index ef30eeb..0000000 --- a/src_test/test_config.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * test_w1.cc - * - * Created on: Oct 20, 2010 - * Author: lamikr - */ -#include -#include -#include "../src/config.h" - -void test_config() { - char work_dir[FILENAME_MAX]; - - getcwd(work_dir, sizeof(work_dir)); - printf("working directory: %s\n", work_dir); - - set_config_value_to_section(work_dir, - "dev_cfg_txt", - "mysection_type", - "mysection_name", - "myoption_name", - "my_option_value_tmp"); - set_config_value_to_section(work_dir, - "dev_cfg_txt", - "mysection_type", - "mysection_name", - "myoption_name", - "my_option_value"); - set_config_value_to_section(work_dir, - "dev_cfg_txt", - "mysection_type", - "mysection_name", - "myoption_name2", - "my_option_value2"); - set_config_value_to_section(work_dir, - "dev_cfg_txt", - "mysection3_type", - "mysection3_name", - "myoption_name", - "my_option_value3"); -} - -int main(int argc, char** argv) { - test_config(); - return 0; -} diff --git a/src_test/test_config1.c b/src_test/test_config1.c new file mode 100644 index 0000000..8bddb50 --- /dev/null +++ b/src_test/test_config1.c @@ -0,0 +1,92 @@ +/* + * test_w1.cc + * + * Created on: Oct 20, 2010 + * Author: lamikr + */ +#include +#include +#include +#include +#include "../src/config.h" + +#define CONF_FILENAME "dev_cfg_txt" +#define SECTION_TYPE "mysection_type" +#define SECTION_TYPE2 "mysection_type2" +#define SECTION_NAME "mysection_name" +#define SECTION_NAME2 "mysection_name2" + +#define KEY_NAME "key_name" +#define KEY_NAME2 "key_name2" +#define KEY_NAME3 "key_name3" +#define KEY_NAME_INVALID_READ "key_name_invalid" + +#define VALUE1 "val1" +#define VALUE2 "val2" +#define VALUE3 "val3" +#define VALUE4 "val4" + +int test_config() { + char work_dir[FILENAME_MAX]; + char *val; + + getcwd(work_dir, sizeof(work_dir)); + printf("working directory: %s\n", work_dir); + + set_config_value_and_save(work_dir, + CONF_FILENAME, + SECTION_TYPE, + SECTION_NAME, + KEY_NAME, + VALUE1); + val = get_config_value_and_close(work_dir, + CONF_FILENAME, + SECTION_NAME, + KEY_NAME); + if ((val != NULL) && + (strcmp(val, VALUE1) == 0)) { + printf("value 1 read ok: %s\n", val); + free(val); + } + else { + printf("failed to read value\n"); + return 1; + } + + val = get_config_value_and_close(work_dir, + CONF_FILENAME, + SECTION_NAME, + KEY_NAME_INVALID_READ); + if ((val != NULL) && + (strcmp(val, VALUE1) == 0)) { + printf("pl, should not be possible to read invalid key value.\n"); + return 0; + } + else { + printf("error, value was supposed to be NULL, but is: %s\n", val); + } + set_config_value_and_save(work_dir, + CONF_FILENAME, + SECTION_TYPE, + SECTION_NAME, + KEY_NAME, + VALUE2); + set_config_value_and_save(work_dir, + CONF_FILENAME, + SECTION_TYPE, + SECTION_NAME, + KEY_NAME2, + VALUE3); + set_config_value_and_save(work_dir, + CONF_FILENAME, + SECTION_TYPE2, + SECTION_NAME2, + KEY_NAME3, + VALUE4); + return 0; +} + +int main(int argc, char** argv) { + test_config(); + return 0; +} diff --git a/src_test/test_config2.c b/src_test/test_config2.c deleted file mode 100644 index dfd0987..0000000 --- a/src_test/test_config2.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * test_w1.cc - * - * Created on: Oct 20, 2010 - * Author: lamikr - */ -#include -#include -#include -#include -#include - -#include "log.h" -#include "config.h" - -/* -static int uci_do_add(int argc, char **argv) -{ - struct uci_package *p = NULL; - struct uci_section *s = NULL; - int ret; - - if (argc != 3) - return 255; - - ret = uci_load(ctx, argv[1], &p); - if (ret != UCI_OK) - goto done; - - ret = uci_add_section(ctx, p, argv[2], &s); - if (ret != UCI_OK) - goto done; - - ret = uci_save(ctx, p); - -done: - if (ret != UCI_OK) - cli_perror(); - else if (s) - fprintf(stdout, "%s\n", s->e.name); - return ret; -} -*/ - -static int uci_create_named_section(struct uci_context *ctx, const char *conf_file_name, const char *section_type, const char *section_name) -{ - struct uci_ptr ptr; - int ret_val; - char *cmd_data; - int len; - - ret_val = -1; - if ((ctx != NULL) && - (conf_file_name != NULL) && - (section_type != NULL) && - (section_name != NULL)) { - len = strlen(conf_file_name); - len = len + 1; - len = len + strlen(section_type); - len = len + 1; - len = len + strlen(section_name); - len = len + 1; - cmd_data = malloc(len); - if (cmd_data != NULL) { - snprintf(cmd_data, len, "%s.%s=%s", conf_file_name, section_name, section_type); - if (uci_lookup_ptr(ctx, &ptr, cmd_data, true) == UCI_OK) { - ret_val = uci_set(ctx, &ptr); - if (ret_val == UCI_OK) { - } - } - free(cmd_data); - } - } - return ret_val; -} - -bool set_config_value2(const char *conf_dir_name, - const char *conf_file_name, - const char *section_type, - const char *section_name, - const char *key, - const char *value) { - struct uci_context *ctx; - struct uci_package *pkg; - struct uci_section *sct; - struct uci_section *tmp_sct; - int err_flg; - char *fname; - int b_count; - struct uci_element *elem; - struct uci_ptr ptr; - FILE *fp; - bool ret_val; - - ret_val = false; - if ((conf_dir_name != NULL) && - (conf_file_name != NULL) && - (section_type != NULL) && - (section_name != NULL) && - (key != NULL) && - (value != NULL)) { - b_count = strlen(conf_dir_name) + strlen(conf_file_name) + 10; - fname = (char *)calloc(1, b_count); - if (fname != NULL) { - strncpy(fname, conf_dir_name, b_count); - strncat(fname, "/", 1); - strncat(fname, conf_file_name, strlen(conf_file_name) + 1); - ctx = uci_alloc_context(); - if (ctx != NULL) { - sct = NULL; - uci_set_confdir(ctx, conf_dir_name); - if (access(fname, W_OK) != 0) { - if (access(fname, F_OK) != 0) { - fp = fopen(fname, "w+"); - fclose(fp); - } - } - if (access(fname, W_OK) == 0) { - err_flg = uci_load(ctx, fname, &pkg); - uci_foreach_element(&pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - if (sct == NULL) { - //err_flg = uci_add_named_section(ctx, pkg, section_type, section_name, &sct); - //err_flg = uci_add_section(ctx, pkg, section_name, &sct); - err_flg = uci_create_named_section(ctx, conf_file_name, section_type, section_name); - if (err_flg == UCI_OK) { - uci_foreach_element(&pkg->sections, elem) { - tmp_sct = uci_to_section(elem); - if (strcmp(tmp_sct->type, section_type) == 0) { - sct = tmp_sct; - break; - } - } - } - } - if (err_flg == 0) { - memset(&ptr, 0, sizeof(ptr)); - ptr.package = pkg->e.name; - ptr.section = sct->e.name; - ptr.option = key; - - if (uci_lookup_ptr(ctx, &ptr, NULL, false) == UCI_OK) { - ptr.value = value; - uci_set(ctx, &ptr); - uci_save(ctx, pkg); - ret_val = true; - log_debug("Created configuration section %s to configuration file: %s\n", section_name, fname); - } - else { - log_error("Could not write to configuration file: %s\n. Could not look-up pointer for package %s section %s.\n", fname, pkg->e.name, sct->e.name); - } - uci_free_context(ctx); - } - else { - log_error("Could not write to configuration file: %s\n. Could not create section %s.\n", fname, section_name); - } - } - else { - log_error("Could not write to configuration file: %s. File does not exist or is not writable.\n", fname); - } - } - free(fname); - } - else { - log_error("Could not change config value, out of memory\n"); - } - } - else { - log_error("Could not change config value, invalid parameters\n"); - } - return ret_val; -} - -void test_config() { - char work_dir[FILENAME_MAX]; - - getcwd(work_dir, sizeof(work_dir)); - printf("working directory: %s\n", work_dir); - - set_config_value2(work_dir, - "dev_cfg_txt", - "mysection_type", - "mysection_name", - "myoption_name", - "my_option_value"); - set_config_value2(work_dir, - "dev_cfg_txt", - "mysection_type", - "mysection_name", - "myoption_name", - "my_option_value2"); -} - -int main(int argc, char** argv) { - test_config(); - return 0; -} diff --git a/src_test/test_config2.cc b/src_test/test_config2.cc new file mode 100644 index 0000000..9b0cf5e --- /dev/null +++ b/src_test/test_config2.cc @@ -0,0 +1,71 @@ +/* + * test_config2.cc + * + * Created on: Aug 3, 2012 + * Author: lamikr + */ +#include +#include "../src/DeviceConfig.hh" +#include "../src/FileUtil.hh" +#include "../src/log.h" + +using namespace plp; +using namespace std; + +#define DEVICE_NAME1 "device_1" +#define KEY_NAME1 "key1" +#define KEY_NAME2 "key2" +#define KEY_NAME3 "key3" + +#define VALUE_NAME1 "val1" +#define VALUE_NAME2 "val2" +#define VALUE_NAME3 "val3" + +int test_config() { + DeviceConfig *dev_cfg; + string val; + string fname_full; + string fname_path; + bool succ; + + DeviceConfig::set_base_dir_name("/tmp/test"); + dev_cfg = new DeviceConfig(DEVICE_NAME1); + fname_full = dev_cfg->get_config_file_name(); + fname_path = FileUtil::parse_directory_path(fname_full.c_str()); + log_info("file-name: %s, path_name: %s\n", + fname_full.c_str(), fname_path.c_str()); + dev_cfg->set_config_value(KEY_NAME1, VALUE_NAME1, false); + // check that read works even if values have not been saved yet + succ = dev_cfg->get_config_value(KEY_NAME1, val); + if (succ) { + log_info("val1: %s\n", val.c_str()); + } + else { + log_error("failed to get value for key: %s\n", KEY_NAME1); + } + dev_cfg->set_config_value(KEY_NAME2, VALUE_NAME2, true); + succ = dev_cfg->get_config_value(KEY_NAME2, val); + if (succ) { + log_info("val2: %s\n", val.c_str()); + } + else { + log_error("failed to get value for key: %s\n", KEY_NAME2); + } + succ = dev_cfg->get_config_value(KEY_NAME2, val); + if (succ) { + log_info("val3: %s\n", val.c_str()); + } + else { + log_error("failed to get value for key: %s\n", KEY_NAME2); + } + dev_cfg->set_config_value(KEY_NAME3, VALUE_NAME3, false); + // check whether device_config destructor will do the final save + delete(dev_cfg); + + return 0; +} + +int main(int argc, char** argv) { + test_config(); + return 0; +} -- 2.41.0