#include <unistd.h>
#include <uci.h>
-#include "log.h"
+#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);
- 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);
- }
- }
- }
- return ret_val;
-}
-
-bool set_config_value(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;
- struct uci_option *opt;
int err_flg;
- char *fname;
+ char *conf_fname_full;
int b_count;
- bool save;
- struct uci_element *elem;
- struct uci_ptr ptr;
FILE *fp;
bool ret_val;
ret_val = false;
- save = 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 (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,
+ key,
+ value,
+ true);
}
- if (sct == NULL) {
- log_debug("Creating configuration 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, 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;
- }
- }
- }
+ else {
+ log_error("Failed to set value to configuration file: %s. Could not load current file content.\n", conf_fname_full);
}
- if (err_flg == 0) {
- opt = uci_lookup_option(ctx, sct, key);
- if (opt != NULL) {
- memset(&ptr, 0, sizeof(ptr));
- ptr.package = pkg->e.name;
- ptr.section = sct->e.name;
- ptr.option = key;
+ }
+ 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;
- if (uci_lookup_ptr(ctx, &ptr, NULL, false) == UCI_OK) {
- ptr.value = strdup(value);
- uci_set(ctx, &ptr);
- save = true;
- }
- }
- else {
- opt = uci_alloc_option(sct, key, value);
- save = true;
- }
- if (save == true) {
- uci_save(ctx, pkg);
- }
- uci_free_context(ctx);
- ret_val = true;
+ 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,
+ &err_flg);
+ // 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("Could not write to configuration file: %s\n. Could not create section %s.", 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("Could not write to configuration file: %s\n. File does not exist or is not writable.", 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("Could not change config value, out of memory");
+ log_error("Failed to get value from configuration file: %s/%s, out of memory.\n", conf_dir_name, conf_file_basename);
}
}
else {
- log_error("Could not change config value, invalid parameters");
+ log_error("Failed to get value from configuration file, invalid parameters.\n");
}
return ret_val;
}