Commit | Line | Data |
---|---|---|
3299fd31 SM |
1 | /* |
2 | * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com> | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0-only | |
5 | * | |
6 | */ | |
7 | ||
c9e313bc | 8 | #include "ini-config.hpp" |
3299fd31 | 9 | |
c9e313bc SM |
10 | #include <common/defaults.hpp> |
11 | #include <common/error.hpp> | |
12 | #include <common/ini-config/ini.hpp> | |
13 | #include <common/macros.hpp> | |
14 | #include <common/utils.hpp> | |
28ab034a | 15 | |
3299fd31 SM |
16 | #include <ctype.h> |
17 | ||
18 | LTTNG_EXPORT const char *config_str_yes = "yes"; | |
19 | LTTNG_EXPORT const char *config_str_true = "true"; | |
20 | LTTNG_EXPORT const char *config_str_on = "on"; | |
21 | LTTNG_EXPORT const char *config_str_no = "no"; | |
22 | LTTNG_EXPORT const char *config_str_false = "false"; | |
23 | LTTNG_EXPORT const char *config_str_off = "off"; | |
24 | ||
f1494934 | 25 | namespace { |
3299fd31 | 26 | struct handler_filter_args { |
28ab034a | 27 | const char *section; |
3299fd31 SM |
28 | config_entry_handler_cb handler; |
29 | void *user_data; | |
30 | }; | |
f1494934 | 31 | } /* namespace */ |
3299fd31 SM |
32 | |
33 | static int config_entry_handler_filter(struct handler_filter_args *args, | |
28ab034a JG |
34 | const char *section, |
35 | const char *name, | |
36 | const char *value) | |
3299fd31 SM |
37 | { |
38 | int ret = 0; | |
39 | struct config_entry entry = { section, name, value }; | |
40 | ||
41 | LTTNG_ASSERT(args); | |
42 | ||
43 | if (!section || !name || !value) { | |
44 | ret = -EIO; | |
45 | goto end; | |
46 | } | |
47 | ||
48 | if (args->section) { | |
5c7248cd | 49 | if (strcmp(args->section, section) != 0) { |
3299fd31 SM |
50 | goto end; |
51 | } | |
52 | } | |
53 | ||
54 | ret = args->handler(&entry, args->user_data); | |
55 | end: | |
56 | return ret; | |
57 | } | |
58 | ||
28ab034a JG |
59 | int config_get_section_entries(const char *override_path, |
60 | const char *section, | |
61 | config_entry_handler_cb handler, | |
62 | void *user_data) | |
3299fd31 SM |
63 | { |
64 | int ret = 0; | |
65 | const char *path; | |
cd9adb8b | 66 | FILE *config_file = nullptr; |
3299fd31 SM |
67 | struct handler_filter_args filter = { section, handler, user_data }; |
68 | ||
69 | /* First, try system-wide conf. file. */ | |
70 | path = DEFAULT_DAEMON_SYSTEM_CONFIGPATH; | |
71 | ||
72 | config_file = fopen(path, "r"); | |
73 | if (config_file) { | |
74 | DBG("Loading daemon conf file at %s", path); | |
75 | /* | |
76 | * Return value is not very important here since error or not, we | |
77 | * continue and try the next possible conf. file. | |
78 | */ | |
79 | (void) ini_parse_file(config_file, | |
28ab034a JG |
80 | (ini_entry_handler) config_entry_handler_filter, |
81 | (void *) &filter); | |
3299fd31 SM |
82 | fclose(config_file); |
83 | } | |
84 | ||
85 | /* Second is the user local configuration. */ | |
86 | path = utils_get_home_dir(); | |
87 | if (path) { | |
88 | char fullpath[PATH_MAX]; | |
89 | ||
28ab034a | 90 | ret = snprintf(fullpath, sizeof(fullpath), DEFAULT_DAEMON_HOME_CONFIGPATH, path); |
3299fd31 SM |
91 | if (ret < 0) { |
92 | PERROR("snprintf user conf. path"); | |
93 | goto error; | |
94 | } | |
95 | ||
96 | config_file = fopen(fullpath, "r"); | |
97 | if (config_file) { | |
98 | DBG("Loading daemon user conf file at %s", path); | |
99 | /* | |
100 | * Return value is not very important here since error or not, we | |
101 | * continue and try the next possible conf. file. | |
102 | */ | |
103 | (void) ini_parse_file(config_file, | |
28ab034a JG |
104 | (ini_entry_handler) config_entry_handler_filter, |
105 | (void *) &filter); | |
3299fd31 SM |
106 | fclose(config_file); |
107 | } | |
108 | } | |
109 | ||
110 | /* Final path is the one that the user might have provided. */ | |
111 | if (override_path) { | |
112 | config_file = fopen(override_path, "r"); | |
113 | if (config_file) { | |
114 | DBG("Loading daemon command line conf file at %s", override_path); | |
115 | (void) ini_parse_file(config_file, | |
28ab034a JG |
116 | (ini_entry_handler) config_entry_handler_filter, |
117 | (void *) &filter); | |
3299fd31 SM |
118 | fclose(config_file); |
119 | } else { | |
28ab034a | 120 | ERR("Failed to open daemon configuration file at %s", override_path); |
3299fd31 SM |
121 | ret = -ENOENT; |
122 | goto error; | |
123 | } | |
124 | } | |
125 | ||
126 | /* Everything went well. */ | |
127 | ret = 0; | |
128 | ||
129 | error: | |
130 | return ret; | |
131 | } | |
132 | ||
133 | int config_parse_value(const char *value) | |
134 | { | |
135 | int i, ret = 0; | |
136 | char *endptr, *lower_str; | |
137 | size_t len; | |
138 | unsigned long v; | |
139 | ||
140 | len = strlen(value); | |
141 | if (!len) { | |
142 | ret = -1; | |
143 | goto end; | |
144 | } | |
145 | ||
146 | v = strtoul(value, &endptr, 10); | |
147 | if (endptr != value) { | |
148 | ret = v; | |
149 | goto end; | |
150 | } | |
151 | ||
64803277 | 152 | lower_str = zmalloc<char>(len + 1); |
3299fd31 SM |
153 | if (!lower_str) { |
154 | PERROR("zmalloc"); | |
155 | ret = -errno; | |
156 | goto end; | |
157 | } | |
158 | ||
159 | for (i = 0; i < len; i++) { | |
160 | lower_str[i] = tolower(value[i]); | |
161 | } | |
162 | ||
28ab034a JG |
163 | if (!strcmp(lower_str, config_str_yes) || !strcmp(lower_str, config_str_true) || |
164 | !strcmp(lower_str, config_str_on)) { | |
3299fd31 | 165 | ret = 1; |
28ab034a JG |
166 | } else if (!strcmp(lower_str, config_str_no) || !strcmp(lower_str, config_str_false) || |
167 | !strcmp(lower_str, config_str_off)) { | |
3299fd31 SM |
168 | ret = 0; |
169 | } else { | |
170 | ret = -1; | |
171 | } | |
172 | ||
173 | free(lower_str); | |
174 | end: | |
175 | return ret; | |
176 | } |