2 * This file is part of buxton.
4 * Copyright (C) 2013 Intel Corporation
6 * buxton is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
18 #include "configurator.h"
23 #include "buxtonarray.h"
27 * Create a BuxtonLayer out of a ConfigLayer
29 * Validates the data from the config file and creates BuxtonLayer.
31 * @param conf_layer the ConfigLayer to validate
33 * @return a new BuxtonLayer. Callers are responsible for managing
36 static BuxtonLayer *buxton_layer_new(ConfigLayer *conf_layer);
38 /* Load layer configurations from disk */
39 void buxton_init_layers(BuxtonConfig *config)
41 Hashmap *layers = NULL;
43 ConfigLayer *config_layers = NULL;
46 nlayers = buxton_key_get_layers(&config_layers);
47 layers = hashmap_new(string_hash_func, string_compare_func);
52 for (int n = 0; n < nlayers; n++) {
55 layer = buxton_layer_new(&(config_layers[n]));
60 r = hashmap_put(layers, layer->name.value, layer);
66 config->layers = layers;
70 static bool is_read_only(ConfigLayer *conf_layer)
72 return strcmp(conf_layer->access, "read-only") == 0;
75 static BuxtonLayer *buxton_layer_new(ConfigLayer *conf_layer)
80 out= malloc0(sizeof(BuxtonLayer));
85 if (conf_layer->priority < 0) {
88 out->name.value = strdup(conf_layer->name);
89 if (!out->name.value) {
92 out->name.length = (uint32_t)strlen(conf_layer->name);
94 if (strcmp(conf_layer->type, "System") == 0) {
95 out->type = LAYER_SYSTEM;
96 } else if (strcmp(conf_layer->type, "User") == 0) {
97 out->type = LAYER_USER;
99 buxton_log("Layer %s has unknown type: %s\n", conf_layer->name, conf_layer->type);
103 if (strcmp(conf_layer->backend, "gdbm") == 0) {
104 out->backend = BACKEND_GDBM;
105 } else if (strcmp(conf_layer->backend, "memory") == 0) {
106 out->backend = BACKEND_MEMORY;
108 buxton_log("Layer %s has unknown database: %s\n", conf_layer->name, conf_layer->backend);
112 if (conf_layer->description != NULL) {
113 out->description = strdup(conf_layer->description);
114 if (!out->description) {
119 out->readonly = is_read_only(conf_layer);
120 out->priority = conf_layer->priority;
123 free(out->name.value);
124 free(out->description);
129 static void init_backend(BuxtonConfig *config,
131 BuxtonBackend **backend)
134 _cleanup_free_ char *path = NULL;
139 module_init_func i_func;
140 module_destroy_func d_func;
141 BuxtonBackend *backend_tmp;
146 if (layer->backend == BACKEND_GDBM) {
148 } else if (layer->backend == BACKEND_MEMORY) {
151 buxton_log("Invalid backend type for layer: %s\n", layer->name);
155 backend_tmp = hashmap_get(config->backends, name);
158 *backend = backend_tmp;
162 backend_tmp = malloc0(sizeof(BuxtonBackend));
167 r = asprintf(&path, "%s/%s.so", buxton_module_dir(), name);
172 /* Load the module */
173 handle = dlopen(path, RTLD_LAZY);
176 buxton_log("dlopen(): %s\n", dlerror());
181 cast = dlsym(handle, "buxton_module_init");
182 if ((error = dlerror()) != NULL || !cast) {
183 buxton_log("dlsym(): %s\n", error);
186 memcpy(&i_func, &cast, sizeof(i_func));
189 cast = dlsym(handle, "buxton_module_destroy");
190 if ((error = dlerror()) != NULL || !cast) {
191 buxton_log("dlsym(): %s\n", error);
194 memcpy(&d_func, &cast, sizeof(d_func));
196 rb = i_func(backend_tmp);
198 buxton_log("buxton_module_init failed\n");
202 if (!config->backends) {
203 config->backends = hashmap_new(trivial_hash_func, trivial_compare_func);
204 if (!config->backends) {
209 r = hashmap_put(config->backends, name, backend_tmp);
214 backend_tmp->module = handle;
215 backend_tmp->destroy = d_func;
217 *backend = backend_tmp;
220 BuxtonBackend *backend_for_layer(BuxtonConfig *config,
223 BuxtonBackend *backend;
228 if (!config->databases) {
229 config->databases = hashmap_new(string_hash_func, string_compare_func);
230 if (!config->databases) {
234 if ((backend = (BuxtonBackend*)hashmap_get(config->databases, layer->name.value)) == NULL) {
235 /* attempt load of backend */
236 init_backend(config, layer, &backend);
238 ret = hashmap_put(config->databases, layer->name.value, backend);
243 return (BuxtonBackend*)hashmap_get(config->databases, layer->name.value);
246 void destroy_backend(BuxtonBackend *backend)
251 backend->set_value = NULL;
252 backend->get_value = NULL;
253 backend->list_keys = NULL;
254 backend->unset_value = NULL;
256 dlclose(backend->module);
262 * Editor modelines - http://www.wireshark.org/tools/modelines.html
267 * indent-tabs-mode: t
270 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
271 * :indentSize=8:tabSize=8:noTabs=false: