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",
66 "BUXTON_SMACK_PERMISSIVE"
71 * keys as they are used in config file
73 static const char *config_keys[CONFIG_MAX] = {
75 NULL, /**< conf file entry in config file is meaningless */
83 static const char *COMPILE_DEFAULT[CONFIG_MAX] = {
85 _DEFAULT_CONFIGURATION_FILE,
95 * wrap strdup and die if malloc fails
97 * @note This may seem lame and stupid at first glance. The former is
98 * right the latter is not. This function may abort()
100 * @return pointer to dup'd string
102 __attribute__ ((pure))
103 static inline char *_strdup(const char* string)
116 * grab a string from the ini file
118 * @param section the section of the ini file
119 * @param name the name of the key
120 * @param required if key required or not
121 * @param def default value for nonrequired setting
123 * @note This function may abort()
125 * @return The value as a string. The the string is internal to
126 * libini, and if at this stage of the game it is null, just die.
127 * Something is really wrong and even if we could recover, the system
128 * is not working correctly.
130 static char *get_ini_string(char *section, char *name, bool required,
137 snprintf(buf, sizeof(buf), "%s:%s", section, name);
138 s = iniparser_getstring(conf.ini, buf, def);
139 if (s == NULL && required) {
146 * analagous method to get_ini_string()
148 * @param section the section of the ini file
149 * @param name the name of the key
150 * @param required if key required or not
151 * @param def default value for nonrequired setting
153 * @note inlined b/c only used once and why not.
157 static inline int get_ini_int(char *section, char *name, bool required,
164 snprintf(buf, sizeof(buf), "%s:%s", section, name);
165 exists = iniparser_find_entry(conf.ini, buf);
166 if (!exists && required) {
169 return iniparser_getint(conf.ini, buf, def);
177 static void initialize(void)
179 if (conf.initialized) {
183 for (int i= CONFIG_MIN+1; i < CONFIG_MAX; i++) {
186 /* hasn't been set through command line */
187 if (conf.keys[i] == NULL) {
188 /* second priority is env */
189 envkey = secure_getenv(KS[i]);
191 conf.keys[i] = _strdup(envkey);
195 /* third priority is conf file */
196 if (conf.keys[i] == NULL && conf.ini) {
197 /* for once config file is loaded */
198 char key[PATH_MAX+strlen(CONFIG_SECTION)+1+1]; /* one for null and one for : */
201 snprintf(key, sizeof(key), "%s:%s", CONFIG_SECTION, config_keys[i]);
202 value = iniparser_getstring(conf.ini, key, NULL);
204 conf.keys[i] = _strdup(value);
208 if (conf.keys[i] == NULL) {
209 /* last priority is compile time defaults */
210 conf.keys[i] = _strdup(COMPILE_DEFAULT[i]);
213 /* if config file is not loaded, load */
214 if (i == CONFIG_CONF_FILE) {
215 char *path = conf.keys[CONFIG_CONF_FILE];
217 conf.ini = iniparser_load(path);
218 if (conf.ini == NULL) {
219 buxton_log("Failed to load buxton conf file: %s\n", path);
223 conf.initialized = true;
228 * use a destructor to free everything rather than yucky at_exit
233 __attribute__ ((destructor)) static void free_conf(void)
235 if (!conf.initialized) {
238 for (int i= CONFIG_MIN+1; i < CONFIG_MAX; i++) {
241 iniparser_freedict(conf.ini);
244 void buxton_add_cmd_line(ConfigKey confkey, const char *data)
246 if (confkey >= CONFIG_MAX || confkey <= CONFIG_MIN) {
247 buxton_log("invalid confkey");
251 buxton_log("invalid data");
255 conf.keys[confkey] = _strdup(data);
258 const char* buxton_module_dir(void)
261 return (const char*)conf.keys[CONFIG_MODULE_DIR];
264 const char* buxton_conf_file(void)
267 return (const char*)conf.keys[CONFIG_CONF_FILE];
270 const char* buxton_db_path(void)
273 return (const char*)conf.keys[CONFIG_DB_PATH];
276 const char* buxton_smack_load_file(void)
279 return (const char*)conf.keys[CONFIG_SMACK_LOAD_FILE];
282 const char* buxton_smack_permissive(void)
285 return (const char*)conf.keys[CONFIG_SMACK_PERMISSIVE];
288 const char* buxton_socket(void)
291 return (const char*)conf.keys[CONFIG_BUXTON_SOCKET];
294 int buxton_key_get_layers(ConfigLayer **layers)
296 ConfigLayer *_layers;
302 if (conf.ini == NULL) {
303 buxton_log("config file not loaded when calling buxton_key_get_layers()");
306 n = iniparser_getnsec(conf.ini);
307 _layers = (ConfigLayer*)calloc((size_t)n, sizeof(ConfigLayer));
308 if (_layers == NULL) {
311 for (int i= 0; i < n; i++) {
314 section_name = iniparser_getsecname(conf.ini, i);
318 if (!strcasecmp(section_name, CONFIG_SECTION)) {
321 _layers[j].name = section_name;
322 _layers[j].description = get_ini_string(section_name,
323 "Description", true, NULL);
324 _layers[j].backend = get_ini_string(section_name, "Backend",
326 _layers[j].type = get_ini_string(section_name, "Type", true,
328 _layers[j].priority = get_ini_int(section_name, "Priority",
330 _layers[j].access = get_ini_string(section_name, "Access",
331 false, "read-write");
338 void include_configurator(void)
345 * Editor modelines - http://www.wireshark.org/tools/modelines.html
350 * indent-tabs-mode: t
353 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
354 * :indentSize=8:tabSize=8:noTabs=false: