#include "config.h"
#include "log.h"
-#define CONFIG_FILE_LINE_MAX 4096
+#define CONFIG_FILE_LINE_MAX ((CONFIG_MAX_NAME + CONFIG_MAX_VALUE + 1024) * 2)
pthread_rwlock_t config_rwlock = PTHREAD_RWLOCK_INITIALIZER;
struct config_value {
avl avl; // the index - this has to be first!
- unsigned long hash; // a simple hash to speed up searching
+ uint32_t hash; // a simple hash to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
- char name[CONFIG_MAX_NAME + 1];
- char value[CONFIG_MAX_VALUE + 1];
+ char *name;
+ char *value;
uint8_t flags;
struct config {
avl avl;
- unsigned long hash; // a simple hash to speed up searching
+ uint32_t hash; // a simple hash to speed up searching
// we first compare hashes, and only if the hashes are equal we do string comparisons
- char name[CONFIG_MAX_NAME + 1];
+ char *name;
struct config_value *values;
avl_tree values_index;
#define config_value_index_add(co, cv) avl_insert(&((co)->values_index), (avl *)(cv))
#define config_value_index_del(co, cv) avl_remove(&((co)->values_index), (avl *)(cv))
-static struct config_value *config_value_index_find(struct config *co, const char *name, unsigned long hash) {
+static struct config_value *config_value_index_find(struct config *co, const char *name, uint32_t hash) {
struct config_value *result = NULL, tmp;
tmp.hash = (hash)?hash:simple_hash(name);
- strncpy(tmp.name, name, CONFIG_MAX_NAME);
- tmp.name[CONFIG_MAX_NAME] = '\0';
+ tmp.name = (char *)name;
avl_search(&(co->values_index), (avl *)&tmp, config_value_iterator, (avl **)&result);
return result;
#define config_index_add(cfg) avl_insert(&config_root_index, (avl *)(cfg))
#define config_index_del(cfg) avl_remove(&config_root_index, (avl *)(cfg))
-static struct config *config_index_find(const char *name, unsigned long hash) {
+static struct config *config_index_find(const char *name, uint32_t hash) {
struct config *result = NULL, tmp;
tmp.hash = (hash)?hash:simple_hash(name);
- strncpy(tmp.name, name, CONFIG_MAX_NAME);
- tmp.name[CONFIG_MAX_NAME] = '\0';
+ tmp.name = (char *)name;
avl_search(&config_root_index, (avl *)&tmp, config_iterator, (avl **)&result);
return result;
struct config_value *cv = calloc(1, sizeof(struct config_value));
if(!cv) fatal("Cannot allocate config_value");
- strncpy(cv->name, name, CONFIG_MAX_NAME);
- strncpy(cv->value, value, CONFIG_MAX_VALUE);
+ cv->name = strdup(name);
+ if(!cv->name) fatal("Cannot allocate config.name");
cv->hash = simple_hash(cv->name);
+ cv->value = strdup(value);
+ if(!cv->value) fatal("Cannot allocate config.value");
+
config_value_index_add(co, cv);
// no need for string termination, due to calloc()
struct config *co = calloc(1, sizeof(struct config));
if(!co) fatal("Cannot allocate config");
- strncpy(co->name, section, CONFIG_MAX_NAME);
+ co->name = strdup(section);
+ if(!co->name) fatal("Cannot allocate config.name");
co->hash = simple_hash(co->name);
+
co->values_index.compar = config_value_compare;
config_index_add(co);
if(!cv) cv = config_value_create(co, name, value);
else {
- if((cv->flags & CONFIG_VALUE_USED && overwrite_used) || !(cv->flags & CONFIG_VALUE_USED)) {
+ if(((cv->flags & CONFIG_VALUE_USED) && overwrite_used) || !(cv->flags & CONFIG_VALUE_USED)) {
debug(D_CONFIG, "Overwriting '%s/%s'.", line, co->name, cv->name);
- strncpy(cv->value, value, CONFIG_MAX_VALUE);
- // termination is already there
+ free(cv->value);
+ cv->value = strdup(value);
+ if(!cv->value) fatal("Cannot allocate config.value");
}
else
debug(D_CONFIG, "Ignoring line %d, '%s/%s' is already present and used.", line, co->name, cv->name);
}
cv->flags |= CONFIG_VALUE_USED;
- if(cv->flags & CONFIG_VALUE_LOADED || cv->flags & CONFIG_VALUE_CHANGED) {
+ if((cv->flags & CONFIG_VALUE_LOADED) || (cv->flags & CONFIG_VALUE_CHANGED)) {
// this is a loaded value from the config file
// if it is different that the default, mark it
if(!(cv->flags & CONFIG_VALUE_CHECKED)) {
s = config_get(section, name, s);
if(!s) return 0;
- if(strcmp(s, "yes") == 0 || strcmp(s, "true") == 0 || strcmp(s, "1") == 0) {
- strcpy(s, "yes");
- return 1;
- }
- else {
- strcpy(s, "no");
- return 0;
- }
+ if(!strcmp(s, "yes")) return 1;
+ else return 0;
}
const char *config_set(const char *section, const char *name, const char *value)
if(strcmp(cv->value, value) != 0) cv->flags |= CONFIG_VALUE_CHANGED;
- strncpy(cv->value, value, CONFIG_MAX_VALUE);
- // termination is already there
+ free(cv->value);
+ cv->value = strdup(value);
+ if(!cv->value) fatal("Cannot allocate config.value");
pthread_rwlock_unlock(&config_rwlock);
web_buffer_printf(wb, "\n# node '%s' is not used.", co->name);
}
- web_buffer_increase(wb, CONFIG_MAX_NAME + 4);
+ web_buffer_increase(wb, CONFIG_FILE_LINE_MAX+1);
web_buffer_printf(wb, "\n[%s]\n", co->name);
for(cv = co->values; cv ; cv = cv->next) {
if(used && !(cv->flags & CONFIG_VALUE_USED)) {
- web_buffer_increase(wb, CONFIG_MAX_NAME + 200);
+ web_buffer_increase(wb, CONFIG_FILE_LINE_MAX + 1);
web_buffer_printf(wb, "\n\t# option '%s' is not used.\n", cv->name);
}
- web_buffer_increase(wb, CONFIG_MAX_NAME + CONFIG_MAX_VALUE + 5);
+ web_buffer_increase(wb, CONFIG_FILE_LINE_MAX + 1);
web_buffer_printf(wb, "\t%s%s = %s\n", ((!(cv->flags & CONFIG_VALUE_CHANGED)) && (cv->flags & CONFIG_VALUE_USED))?"# ":"", cv->name, cv->value);
}
}