+/*
+ * Copyright (C) 2013 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <config.h>
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <common/defaults.h>
+#include <common/error.h>
+#include <common/macros.h>
+#include <common/utils.h>
+
+#include "config.h"
+
+struct handler_filter_args {
+ const char* section;
+ config_entry_handler_cb handler;
+ void *user_data;
+};
+
+const char * const config_str_yes = "yes";
+const char * const config_str_true = "true";
+const char * const config_str_on = "on";
+const char * const config_str_no = "no";
+const char * const config_str_false = "false";
+const char * const config_str_off = "off";
+
+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 };
+
+ 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;
+}
+
+LTTNG_HIDDEN
+int config_get_section_entries(const char *override_path, const char *section,
+ config_entry_handler_cb handler, void *user_data)
+{
+ int ret = 0;
+ FILE *config_file = NULL;
+ struct handler_filter_args filter = { section, handler, user_data };
+
+ if (override_path) {
+ config_file = fopen(override_path, "r");
+ if (config_file) {
+ DBG("Loaded daemon configuration file at %s",
+ override_path);
+ } else {
+ ERR("Failed to open daemon configuration file at %s",
+ override_path);
+ ret = -ENOENT;
+ goto end;
+ }
+ } else {
+ char *path = utils_get_home_dir();
+
+ /* Try to open the user's daemon configuration file */
+ if (path) {
+ ret = asprintf(&path, DEFAULT_DAEMON_HOME_CONFIGPATH, path);
+ if (ret < 0) {
+ goto end;
+ }
+
+ ret = 0;
+ config_file = fopen(path, "r");
+ if (config_file) {
+ DBG("Loaded daemon configuration file at %s", path);
+ }
+
+ free(path);
+ }
+
+ /* Try to open the system daemon configuration file */
+ if (!config_file) {
+ config_file = fopen(DEFAULT_DAEMON_HOME_CONFIGPATH, "r");
+ }
+ }
+
+ if (!config_file) {
+ DBG("No daemon configuration file found.");
+ goto end;
+ }
+
+ ret = ini_parse_file(config_file,
+ (ini_entry_handler) config_entry_handler_filter, (void *) &filter);
+
+end:
+ return ret;
+}
+
+LTTNG_HIDDEN
+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 = 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;
+}