const char* key;
void* value;
+ size_t length;
// Callbacks
nw_config_option_read_callback_t read_callback;
struct nw_config {
int nrefs;
- // The path to the configuration file
- char path[PATH_MAX];
-
STAILQ_HEAD(config_entries, nw_config_entry) entries;
// Options
free(config);
}
-int nw_config_create(nw_config** config, const char* path) {
+int nw_config_create(nw_config** config, FILE* f) {
int r;
nw_config* c = calloc(1, sizeof(*c));
// Initialise options
STAILQ_INIT(&c->options);
- // Store the path
- if (path) {
- r = nw_string_set(c->path, path);
- if (r)
- goto ERROR;
-
- // Try to read the configuration from path
- r = nw_config_read(c);
- if (r)
+ // Read configuration
+ if (f) {
+ r = nw_config_read(c, f);
+ if (r < 0)
goto ERROR;
}
return r;
}
+int nw_config_open(nw_config** config, const char* path) {
+ FILE* f = NULL;
+ int r;
+
+ // Open path
+ f = fopen(path, "r");
+ if (!f)
+ return -errno;
+
+ // Create a new configuration
+ r = nw_config_create(config, f);
+
+ERROR:
+ if (f)
+ fclose(f);
+
+ return r;
+}
+
nw_config* nw_config_ref(nw_config* config) {
config->nrefs++;
return NULL;
}
-int nw_config_destroy(nw_config* config) {
- int r;
-
- // Drop all entries
- r = nw_config_flush(config);
- if (r)
- return r;
-
- return unlink(config->path);
-}
-
int nw_config_copy(nw_config* config, nw_config** copy) {
struct nw_config_entry* entry = NULL;
nw_config* c = NULL;
return r;
}
-const char* nw_config_path(nw_config* config) {
- if (*config->path)
- return config->path;
-
- return NULL;
-}
-
int nw_config_flush(nw_config* config) {
struct nw_config_entry* entry = NULL;
return 0;
}
-static int nw_config_readf(nw_config* config, FILE* f) {
+int nw_config_read(nw_config* config, FILE* f) {
char* line = NULL;
size_t length = 0;
int r;
return r;
}
-int nw_config_read(nw_config* config) {
- FILE* f = NULL;
- int r;
-
- // We cannot read if path is not set
- if (!*config->path) {
- errno = ENOTSUP;
- return 1;
- }
-
- // Open the file
- f = fopen(config->path, "r");
- if (!f) {
- // Silently ignore if the file does not exist
- if (errno == ENOENT)
- return 0;
-
- ERROR("Could not read configuration file %s: %m\n", config->path);
- r = 1;
- goto ERROR;
- }
-
- // Read from file
- r = nw_config_readf(config, f);
-
-ERROR:
- if (f)
- fclose(f);
-
- return r;
-}
-
-static int nw_config_writef(nw_config* config, FILE* f) {
+int nw_config_write(nw_config* config, FILE* f) {
struct nw_config_entry* entry = NULL;
int r;
return 0;
}
-int nw_config_write(nw_config* config) {
- int r;
-
- // We cannot write if path is not set
- if (!*config->path) {
- errno = ENOTSUP;
- return 1;
- }
-
- FILE* f = fopen(config->path, "w");
- if (!f) {
- ERROR("Failed to open %s for writing: %m\n", config->path);
- r = 1;
- goto ERROR;
- }
-
- // Write configuration
- r = nw_config_writef(config, f);
-
-ERROR:
- if (f)
- fclose(f);
-
- return r;
-}
-
static struct nw_config_entry* nw_config_find(nw_config* config, const char* key) {
struct nw_config_entry* entry = NULL;
int r;
STAILQ_FOREACH(option, &config->options, nodes) {
- r = option->read_callback(config, option->key, option->value, option->data);
+ r = option->read_callback(config,
+ option->key, option->value, option->length, option->data);
if (r < 0)
return r;
}
int r;
STAILQ_FOREACH(option, &config->options, nodes) {
- r = option->write_callback(config, option->key, option->value, option->data);
+ r = option->write_callback(config,
+ option->key, option->value, option->length, option->data);
if (r < 0)
return r;
}
return 0;
}
-int nw_config_option_add(nw_config* config, const char* key, void* value,
+int nw_config_option_add(nw_config* config,
+ const char* key, void* value, const size_t length,
nw_config_option_read_callback_t read_callback,
nw_config_option_write_callback_t write_callback, void* data) {
// Check input
// Set value
option->value = value;
+ option->length = length;
// Set callbacks
option->read_callback = read_callback;
return 0;
}
-int nw_config_read_int(nw_config* config, const char* key, void* value, void* data) {
+int nw_config_read_int(nw_config* config,
+ const char* key, void* value, const size_t length, void* data) {
// Fetch the value
*(int*)value = nw_config_get_int(config, key, -1);
}
int nw_config_write_int(nw_config* config,
- const char* key, const void* value, void* data) {
+ const char* key, const void* value, const size_t length, void* data) {
return 0;
}
// String
-int nw_config_read_string(nw_config* config, const char* key, void* value, void* data) {
+int nw_config_read_string(nw_config* config,
+ const char* key, void* value, const size_t length, void* data) {
// Fetch the value
const char* p = nw_config_get(config, key);
if (p)
}
int nw_config_write_string(nw_config* config,
- const char* key, const void* value, void* data) {
+ const char* key, const void* value, const size_t length, void* data) {
return nw_config_set(config, key, *(const char**)value);
}
+// String Buffer
+
+int nw_config_read_string_buffer(nw_config* config,
+ const char* key, void* value, const size_t length, void* data) {
+ char* string = (char*)value;
+
+ // Fetch the value
+ const char* p = nw_config_get(config, key);
+ if (p)
+ return __nw_string_set(string, length, p);
+
+ return 0;
+}
+
+// String Table
+
+int nw_config_read_string_table(nw_config* config,
+ const char* key, void* value, const size_t length, void* data) {
+ const char* s = NULL;
+ int* v = (int*)value;
+
+ const nw_string_table_t* table = (nw_string_table_t*)data;
+
+ // Fetch the string
+ s = nw_config_get(config, key);
+ if (!s)
+ return -errno;
+
+ // Lookup the string in the table
+ *v = nw_string_table_lookup_id(table, s);
+
+ // If the result is negative, nothing was found
+ if (*v < 0)
+ return -EINVAL;
+
+ return 0;
+}
+
+int nw_config_write_string_table(nw_config* config,
+ const char* key, const void* value, const size_t length, void* data) {
+ int* v = (int*)value;
+
+ const nw_string_table_t* table = (nw_string_table_t*)data;
+
+ // Lookup the string
+ const char* s = nw_string_table_lookup_string(table, *v);
+ if (!s)
+ return -errno;
+
+ return nw_config_set(config, key, s);
+}
+
// Address
-int nw_config_read_address(nw_config* config, const char* key, void* value, void* data) {
+int nw_config_read_address(nw_config* config,
+ const char* key, void* value, const size_t length, void* data) {
nw_address_t* address = (nw_address_t*)value;
int r;
}
int nw_config_write_address(nw_config* config,
- const char* key, const void* value, void* data) {
+ const char* key, const void* value, const size_t length, void* data) {
const nw_address_t* address = (nw_address_t*)value;
int r;