Add libconfig implementation and tests
[lttng-tools.git] / src / common / config / config.c
CommitLineData
1501a7f3
JG
1/*
2 * Copyright (C) 2013 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 */
17
18#define _GNU_SOURCE
19#include <assert.h>
20#include <config.h>
21#include <ctype.h>
22#include <errno.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26
27#include <common/defaults.h>
28#include <common/error.h>
29#include <common/macros.h>
30#include <common/utils.h>
31
32#include "config.h"
33
34struct handler_filter_args {
35 const char* section;
36 config_entry_handler_cb handler;
37 void *user_data;
38};
39
40const char * const config_str_yes = "yes";
41const char * const config_str_true = "true";
42const char * const config_str_on = "on";
43const char * const config_str_no = "no";
44const char * const config_str_false = "false";
45const char * const config_str_off = "off";
46
47static int config_entry_handler_filter(struct handler_filter_args *args,
48 const char *section, const char *name, const char *value)
49{
50 int ret = 0;
51 struct config_entry entry = { section, name, value };
52
53 assert(args);
54
55 if (!section || !name || !value) {
56 ret = -EIO;
57 goto end;
58 }
59
60 if (args->section) {
61 if (strcmp(args->section, section)) {
62 goto end;
63 }
64 }
65
66 ret = args->handler(&entry, args->user_data);
67end:
68 return ret;
69}
70
71LTTNG_HIDDEN
72int config_get_section_entries(const char *override_path, const char *section,
73 config_entry_handler_cb handler, void *user_data)
74{
75 int ret = 0;
76 FILE *config_file = NULL;
77 struct handler_filter_args filter = { section, handler, user_data };
78
79 if (override_path) {
80 config_file = fopen(override_path, "r");
81 if (config_file) {
82 DBG("Loaded daemon configuration file at %s",
83 override_path);
84 } else {
85 ERR("Failed to open daemon configuration file at %s",
86 override_path);
87 ret = -ENOENT;
88 goto end;
89 }
90 } else {
91 char *path = utils_get_home_dir();
92
93 /* Try to open the user's daemon configuration file */
94 if (path) {
95 ret = asprintf(&path, DEFAULT_DAEMON_HOME_CONFIGPATH, path);
96 if (ret < 0) {
97 goto end;
98 }
99
100 ret = 0;
101 config_file = fopen(path, "r");
102 if (config_file) {
103 DBG("Loaded daemon configuration file at %s", path);
104 }
105
106 free(path);
107 }
108
109 /* Try to open the system daemon configuration file */
110 if (!config_file) {
111 config_file = fopen(DEFAULT_DAEMON_HOME_CONFIGPATH, "r");
112 }
113 }
114
115 if (!config_file) {
116 DBG("No daemon configuration file found.");
117 goto end;
118 }
119
120 ret = ini_parse_file(config_file,
121 (ini_entry_handler) config_entry_handler_filter, (void *) &filter);
122
123end:
124 return ret;
125}
126
127LTTNG_HIDDEN
128int config_parse_value(const char *value)
129{
130 int i, ret = 0;
131 char *endptr, *lower_str;
132 size_t len;
133 unsigned long v;
134
135 len = strlen(value);
136 if (!len) {
137 ret = -1;
138 goto end;
139 }
140
141 v = strtoul(value, &endptr, 10);
142 if (endptr != value) {
143 ret = v;
144 goto end;
145 }
146
147 lower_str = zmalloc(len + 1);
148 if (!lower_str) {
149 PERROR("zmalloc");
150 ret = -errno;
151 goto end;
152 }
153
154 for (i = 0; i < len; i++) {
155 lower_str[i] = tolower(value[i]);
156 }
157
158 if (!strcmp(lower_str, config_str_yes) ||
159 !strcmp(lower_str, config_str_true) ||
160 !strcmp(lower_str, config_str_on)) {
161 ret = 1;
162 } else if (!strcmp(lower_str, config_str_no) ||
163 !strcmp(lower_str, config_str_false) ||
164 !strcmp(lower_str, config_str_off)) {
165 ret = 0;
166 } else {
167 ret = -1;
168 }
169
170 free(lower_str);
171end:
172 return ret;
173}
This page took 0.028245 seconds and 4 git commands to generate.