common: split ini-config in its own convenience library
[lttng-tools.git] / src / common / ini-config / ini-config.cpp
diff --git a/src/common/ini-config/ini-config.cpp b/src/common/ini-config/ini-config.cpp
new file mode 100644 (file)
index 0000000..797de01
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+#include "ini-config.h"
+
+#include <common/defaults.h>
+#include <common/error.h>
+#include <common/ini-config/ini.h>
+#include <common/macros.h>
+#include <common/utils.h>
+#include <ctype.h>
+
+LTTNG_EXPORT const char *config_str_yes = "yes";
+LTTNG_EXPORT const char *config_str_true = "true";
+LTTNG_EXPORT const char *config_str_on = "on";
+LTTNG_EXPORT const char *config_str_no = "no";
+LTTNG_EXPORT const char *config_str_false = "false";
+LTTNG_EXPORT const char *config_str_off = "off";
+
+struct handler_filter_args {
+       const char* section;
+       config_entry_handler_cb handler;
+       void *user_data;
+};
+
+static int config_entry_handler_filter(struct handler_filter_args *args,
+               const char *section, const char *name, const char *value)
+{
+       int ret = 0;
+       struct config_entry entry = { section, name, value };
+
+       LTTNG_ASSERT(args);
+
+       if (!section || !name || !value) {
+               ret = -EIO;
+               goto end;
+       }
+
+       if (args->section) {
+               if (strcmp(args->section, section)) {
+                       goto end;
+               }
+       }
+
+       ret = args->handler(&entry, args->user_data);
+end:
+       return ret;
+}
+
+int config_get_section_entries(const char *override_path, const char *section,
+               config_entry_handler_cb handler, void *user_data)
+{
+       int ret = 0;
+       const char *path;
+       FILE *config_file = NULL;
+       struct handler_filter_args filter = { section, handler, user_data };
+
+       /* First, try system-wide conf. file. */
+       path = DEFAULT_DAEMON_SYSTEM_CONFIGPATH;
+
+       config_file = fopen(path, "r");
+       if (config_file) {
+               DBG("Loading daemon conf file at %s", path);
+               /*
+                * Return value is not very important here since error or not, we
+                * continue and try the next possible conf. file.
+                */
+               (void) ini_parse_file(config_file,
+                               (ini_entry_handler) config_entry_handler_filter,
+                               (void *) &filter);
+               fclose(config_file);
+       }
+
+       /* Second is the user local configuration. */
+       path = utils_get_home_dir();
+       if (path) {
+               char fullpath[PATH_MAX];
+
+               ret = snprintf(fullpath, sizeof(fullpath),
+                               DEFAULT_DAEMON_HOME_CONFIGPATH, path);
+               if (ret < 0) {
+                       PERROR("snprintf user conf. path");
+                       goto error;
+               }
+
+               config_file = fopen(fullpath, "r");
+               if (config_file) {
+                       DBG("Loading daemon user conf file at %s", path);
+                       /*
+                        * Return value is not very important here since error or not, we
+                        * continue and try the next possible conf. file.
+                        */
+                       (void) ini_parse_file(config_file,
+                                       (ini_entry_handler) config_entry_handler_filter,
+                                       (void *) &filter);
+                       fclose(config_file);
+               }
+       }
+
+       /* Final path is the one that the user might have provided. */
+       if (override_path) {
+               config_file = fopen(override_path, "r");
+               if (config_file) {
+                       DBG("Loading daemon command line conf file at %s", override_path);
+                       (void) ini_parse_file(config_file,
+                                       (ini_entry_handler) config_entry_handler_filter,
+                                       (void *) &filter);
+                       fclose(config_file);
+               } else {
+                       ERR("Failed to open daemon configuration file at %s",
+                               override_path);
+                       ret = -ENOENT;
+                       goto error;
+               }
+       }
+
+       /* Everything went well. */
+       ret = 0;
+
+error:
+       return ret;
+}
+
+int config_parse_value(const char *value)
+{
+       int i, ret = 0;
+       char *endptr, *lower_str;
+       size_t len;
+       unsigned long v;
+
+       len = strlen(value);
+       if (!len) {
+               ret = -1;
+               goto end;
+       }
+
+       v = strtoul(value, &endptr, 10);
+       if (endptr != value) {
+               ret = v;
+               goto end;
+       }
+
+       lower_str = (char *) zmalloc(len + 1);
+       if (!lower_str) {
+               PERROR("zmalloc");
+               ret = -errno;
+               goto end;
+       }
+
+       for (i = 0; i < len; i++) {
+               lower_str[i] = tolower(value[i]);
+       }
+
+       if (!strcmp(lower_str, config_str_yes) ||
+               !strcmp(lower_str, config_str_true) ||
+               !strcmp(lower_str, config_str_on)) {
+               ret = 1;
+       } else if (!strcmp(lower_str, config_str_no) ||
+               !strcmp(lower_str, config_str_false) ||
+               !strcmp(lower_str, config_str_off)) {
+               ret = 0;
+       } else {
+               ret = -1;
+       }
+
+       free(lower_str);
+end:
+       return ret;
+}
This page took 0.024801 seconds and 4 git commands to generate.