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.
17 #include <iniparser.h>
18 #include <linux/limits.h>
24 #include "configurator.h"
28 * Section name in ini file for our configuration
30 #define CONFIG_SECTION "Configuration"
32 #ifndef HAVE_SECURE_GETENV
33 # ifdef HAVE___SECURE_GETENV
34 # define secure_getenv __secure_getenv
36 # error neither secure_getenv nor __secure_getenv is available
42 * internal state of configurator
45 bool initialized; /**< track if it's been init'd */
46 char* keys[CONFIG_MAX]; /**< bag of values */
47 dictionary* ini; /**< ini parser dictionary */
56 * config keys as in environment
59 static const char *KS[CONFIG_MAX] = {
64 "BUXTON_SMACK_LOAD_FILE",
65 "BUXTON_BUXTON_SOCKET"
70 * keys as they are used in config file
72 static const char *config_keys[CONFIG_MAX] = {
74 NULL, /**< conf file entry in config file is meaningless */
81 static const char *COMPILE_DEFAULT[CONFIG_MAX] = {
83 _DEFAULT_CONFIGURATION_FILE,
92 * wrap strdup and die if malloc fails
94 * @note This may seem lame and stupid at first glance. The former is
95 * right the latter is not. This function may abort()
97 * @return pointer to dup'd string
99 __attribute__ ((pure))
100 static inline char *_strdup(const char* string)
113 * grab a string from the ini file
115 * @param section the section of the ini file
116 * @param name the name of the key
117 * @param required if key required or not
118 * @param def default value for nonrequired setting
120 * @note This function may abort()
122 * @return The value as a string. The the string is internal to
123 * libini, and if at this stage of the game it is null, just die.
124 * Something is really wrong and even if we could recover, the system
125 * is not working correctly.
127 static char *get_ini_string(char *section, char *name, bool required,
134 snprintf(buf, sizeof(buf), "%s:%s", section, name);
135 s = iniparser_getstring(conf.ini, buf, def);
136 if (s == NULL && required) {
143 * analagous method to get_ini_string()
145 * @param section the section of the ini file
146 * @param name the name of the key
147 * @param required if key required or not
148 * @param def default value for nonrequired setting
150 * @note inlined b/c only used once and why not.
154 static inline int get_ini_int(char *section, char *name, bool required,
161 snprintf(buf, sizeof(buf), "%s:%s", section, name);
162 exists = iniparser_find_entry(conf.ini, buf);
163 if (!exists && required) {
166 return iniparser_getint(conf.ini, buf, def);
174 static void initialize(void)
176 if (conf.initialized) {
180 for (int i= CONFIG_MIN+1; i < CONFIG_MAX; i++) {
183 /* hasn't been set through command line */
184 if (conf.keys[i] == NULL) {
185 /* second priority is env */
186 envkey = secure_getenv(KS[i]);
188 conf.keys[i] = _strdup(envkey);
192 /* third priority is conf file */
193 if (conf.keys[i] == NULL && conf.ini) {
194 /* for once config file is loaded */
195 char key[PATH_MAX+strlen(CONFIG_SECTION)+1+1]; /* one for null and one for : */
198 snprintf(key, sizeof(key), "%s:%s", CONFIG_SECTION, config_keys[i]);
199 value = iniparser_getstring(conf.ini, key, NULL);
201 conf.keys[i] = _strdup(value);
205 if (conf.keys[i] == NULL) {
206 /* last priority is compile time defaults */
207 conf.keys[i] = _strdup(COMPILE_DEFAULT[i]);
210 /* if config file is not loaded, load */
211 if (i == CONFIG_CONF_FILE) {
212 char *path = conf.keys[CONFIG_CONF_FILE];
214 conf.ini = iniparser_load(path);
215 if (conf.ini == NULL) {
216 buxton_log("Failed to load buxton conf file: %s\n", path);
220 conf.initialized = true;
225 * use a destructor to free everything rather than yucky at_exit
230 __attribute__ ((destructor)) static void free_conf(void)
232 if (!conf.initialized) {
235 for (int i= CONFIG_MIN+1; i < CONFIG_MAX; i++) {
238 iniparser_freedict(conf.ini);
241 void buxton_add_cmd_line(ConfigKey confkey, char* data)
243 if (confkey >= CONFIG_MAX || confkey <= CONFIG_MIN) {
244 buxton_log("invalid confkey");
248 buxton_log("invalid data");
252 conf.keys[confkey] = _strdup(data);
255 const char* buxton_module_dir(void)
258 return (const char*)conf.keys[CONFIG_MODULE_DIR];
261 const char* buxton_conf_file(void)
264 return (const char*)conf.keys[CONFIG_CONF_FILE];
267 const char* buxton_db_path(void)
270 return (const char*)conf.keys[CONFIG_DB_PATH];
273 const char* buxton_smack_load_file(void)
276 return (const char*)conf.keys[CONFIG_SMACK_LOAD_FILE];
279 const char* buxton_socket(void)
282 return (const char*)conf.keys[CONFIG_BUXTON_SOCKET];
285 int buxton_key_get_layers(ConfigLayer **layers)
287 ConfigLayer *_layers;
293 if (conf.ini == NULL) {
294 buxton_log("config file not loaded when calling buxton_key_get_layers()");
297 n = iniparser_getnsec(conf.ini);
298 _layers = (ConfigLayer*)calloc((size_t)n, sizeof(ConfigLayer));
299 if (_layers == NULL) {
302 for (int i= 0; i < n; i++) {
305 section_name = iniparser_getsecname(conf.ini, i);
309 if (!strcasecmp(section_name, CONFIG_SECTION)) {
312 _layers[j].name = section_name;
313 _layers[j].description = get_ini_string(section_name,
314 "Description", true, NULL);
315 _layers[j].backend = get_ini_string(section_name, "Backend",
317 _layers[j].type = get_ini_string(section_name, "Type", true,
319 _layers[j].priority = get_ini_int(section_name, "Priority",
321 _layers[j].access = get_ini_string(section_name, "Access",
322 false, "read-write");
329 void include_configurator(void)
336 * Editor modelines - http://www.wireshark.org/tools/modelines.html
341 * indent-tabs-mode: t
344 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
345 * :indentSize=8:tabSize=8:noTabs=false: