Use compiler-agnostic defines to silence warning
[lttng-tools.git] / src / bin / lttng / conf.cpp
CommitLineData
f3ed775e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
f3ed775e 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
f3ed775e 5 *
f3ed775e
DG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
28ab034a
JG
9#include "conf.hpp"
10
11#include <common/common.hpp>
12#include <common/compat/errno.hpp>
13#include <common/utils.hpp>
14
f3ed775e
DG
15#include <limits.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <sys/stat.h>
20#include <sys/types.h>
21#include <unistd.h>
22
f3ed775e 23/*
28eee19b
FG
24 * Returns the path with '/CONFIG_FILENAME' added to it;
25 * path will be NULL if an error occurs.
f3ed775e 26 */
9b27c721 27char *config_get_file_path(const char *path)
f3ed775e
DG
28{
29 int ret;
30 char *file_path;
31
32 ret = asprintf(&file_path, "%s/%s", path, CONFIG_FILENAME);
33 if (ret < 0) {
34 ERR("Fail allocating config file path");
cd9adb8b 35 file_path = nullptr;
f3ed775e
DG
36 }
37
38 return file_path;
39}
40
41/*
28eee19b
FG
42 * Returns an open FILE pointer to the config file;
43 * on error, NULL is returned.
f3ed775e 44 */
9b27c721 45static FILE *open_config(const char *path, const char *mode)
f3ed775e 46{
cd9adb8b 47 FILE *fp = nullptr;
f3ed775e
DG
48 char *file_path;
49
58a97671 50 file_path = config_get_file_path(path);
cd9adb8b 51 if (file_path == nullptr) {
f3ed775e
DG
52 goto error;
53 }
54
55 fp = fopen(file_path, mode);
cd9adb8b 56 if (fp == nullptr) {
dcffe946 57 PWARN("Failed to open configuration file '%s'", file_path);
f3ed775e
DG
58 goto error;
59 }
60
61error:
0e428499 62 free(file_path);
f3ed775e
DG
63 return fp;
64}
65
66/*
28eee19b
FG
67 * Creates the empty config file at the path.
68 * On success, returns 0;
69 * on error, returns -1.
f3ed775e 70 */
4f00620d 71static int create_config_file(const char *path)
f3ed775e
DG
72{
73 int ret;
74 FILE *fp;
75
76 fp = open_config(path, "w+");
cd9adb8b 77 if (fp == nullptr) {
f3ed775e
DG
78 ret = -1;
79 goto error;
80 }
81
82 ret = fclose(fp);
83
84error:
85 return ret;
86}
87
f3ed775e 88/*
28eee19b
FG
89 * Append data to the config file in file_path
90 * On success, returns 0;
91 * on error, returns -1.
f3ed775e 92 */
aedbbb5d 93static int write_config(const char *file_path, std::size_t size, const char *data)
f3ed775e
DG
94{
95 FILE *fp;
aedbbb5d 96 std::size_t len;
a079cd4d 97 int ret = 0;
f3ed775e
DG
98
99 fp = open_config(file_path, "a");
cd9adb8b 100 if (fp == nullptr) {
a079cd4d
MD
101 ret = -1;
102 goto end;
f3ed775e
DG
103 }
104
105 /* Write session name into config file */
a079cd4d 106 len = fwrite(data, size, 1, fp);
27089920 107 if (len != 1) {
a079cd4d
MD
108 ret = -1;
109 }
f66c074c
DG
110 if (fclose(fp)) {
111 PERROR("close write_config");
112 }
a079cd4d
MD
113end:
114 return ret;
f3ed775e
DG
115}
116
f3ed775e 117/*
28eee19b 118 * Destroys directory config and file config.
f3ed775e 119 */
9b27c721 120void config_destroy(const char *path)
f3ed775e
DG
121{
122 int ret;
123 char *config_path;
124
58a97671 125 config_path = config_get_file_path(path);
cd9adb8b 126 if (config_path == nullptr) {
58a97671
DG
127 return;
128 }
f3ed775e 129
d6a07e7d
FG
130 if (!config_exists(config_path)) {
131 goto end;
132 }
133
134 DBG("Removing %s\n", config_path);
f3ed775e
DG
135 ret = remove(config_path);
136 if (ret < 0) {
6f04ed72 137 PERROR("remove config file");
f3ed775e 138 }
d6a07e7d 139end:
f3ed775e
DG
140 free(config_path);
141}
142
d6a07e7d 143/*
28eee19b 144 * Destroys the default config
d6a07e7d 145 */
cd9adb8b 146void config_destroy_default()
d6a07e7d 147{
4f00620d 148 const char *path = utils_get_home_dir();
cd9adb8b 149 if (path == nullptr) {
d6a07e7d
FG
150 return;
151 }
152 config_destroy(path);
153}
154
155/*
28eee19b 156 * Returns 1 if config exists, 0 otherwise
d6a07e7d
FG
157 */
158int config_exists(const char *path)
159{
160 int ret;
161 struct stat info;
162
163 ret = stat(path, &info);
164 if (ret < 0) {
165 return 0;
166 }
167 return S_ISREG(info.st_mode) || S_ISDIR(info.st_mode);
168}
169
28ab034a 170static int _config_read_session_name(const char *path, char **name)
f3ed775e 171{
1dac0189 172 int ret = 0;
f3ed775e
DG
173 FILE *fp;
174 char var[NAME_MAX], *session_name;
09b72f7a 175
8ab7c0d9 176#if (NAME_MAX == 255)
28ab034a 177#define NAME_MAX_SCANF_IS_A_BROKEN_API "254"
8ab7c0d9 178#endif
f3ed775e 179
64803277 180 session_name = calloc<char>(NAME_MAX);
cd9adb8b 181 if (session_name == nullptr) {
1dac0189 182 ret = -ENOMEM;
27089920
TD
183 ERR("Out of memory");
184 goto error;
185 }
186
f3ed775e 187 fp = open_config(path, "r");
cd9adb8b 188 if (fp == nullptr) {
1dac0189 189 ret = -ENOENT;
f3ed775e
DG
190 goto error;
191 }
192
f3ed775e 193 while (!feof(fp)) {
28ab034a
JG
194 if ((ret = fscanf(fp,
195 "%" NAME_MAX_SCANF_IS_A_BROKEN_API
196 "[^'=']=%" NAME_MAX_SCANF_IS_A_BROKEN_API "s\n",
197 var,
198 session_name)) != 2) {
f3ed775e
DG
199 if (ret == -1) {
200 ERR("Missing session=NAME in config file.");
00f36863 201 goto error_close;
f3ed775e
DG
202 }
203 continue;
204 }
205
206 if (strcmp(var, "session") == 0) {
207 goto found;
208 }
209 }
210
00f36863 211error_close:
1dac0189 212 if (fclose(fp) < 0) {
f66c074c
DG
213 PERROR("close config read session name");
214 }
f3ed775e 215error:
1dac0189
PPM
216 free(session_name);
217 return ret;
f3ed775e 218found:
1dac0189
PPM
219 *name = session_name;
220 if (fclose(fp) < 0) {
f66c074c
DG
221 PERROR("close config read session name found");
222 }
1dac0189
PPM
223 return ret;
224}
225
226/*
227 * Returns the session name from the config file.
228 *
229 * The caller is responsible for freeing the returned string.
230 * On error, NULL is returned.
231 */
9b27c721 232char *config_read_session_name(const char *path)
1dac0189
PPM
233{
234 int ret;
cd9adb8b 235 char *name = nullptr;
1dac0189
PPM
236
237 ret = _config_read_session_name(path, &name);
238 if (ret == -ENOENT) {
239 const char *home_dir = utils_get_home_dir();
240
241 ERR("Can't find valid lttng config %s/.lttngrc", home_dir);
242 MSG("Did you create a session? (lttng create <my_session>)");
243 }
244
245 return name;
246}
247
248/*
249 * Returns the session name from the config file. (no warnings/errors emitted)
250 *
251 * The caller is responsible for freeing the returned string.
252 * On error, NULL is returned.
253 */
9b27c721 254char *config_read_session_name_quiet(const char *path)
1dac0189 255{
cd9adb8b 256 char *name = nullptr;
f3ed775e 257
1dac0189
PPM
258 (void) _config_read_session_name(path, &name);
259 return name;
f3ed775e
DG
260}
261
262/*
28eee19b
FG
263 * Write session name option to the config file.
264 * On success, returns 0;
265 * on error, returns -1.
f3ed775e 266 */
9b27c721 267int config_add_session_name(const char *path, const char *name)
f3ed775e 268{
aedbbb5d
JG
269 std::string attribute;
270 try {
271 attribute = fmt::format("session={}", name);
272 } catch (const std::exception& ex) {
273 ERR_FMT("Failed to format session name attribute for configuration file: {}",
274 ex.what());
275 return -1;
f3ed775e 276 }
aedbbb5d
JG
277
278 return write_config(path, attribute.size(), attribute.c_str());
f3ed775e
DG
279}
280
f3ed775e 281/*
28eee19b
FG
282 * Init configuration directory and file.
283 * On success, returns 0;
284 * on error, returns -1.
f3ed775e 285 */
9b27c721 286int config_init(const char *session_name)
f3ed775e
DG
287{
288 int ret;
4f00620d 289 const char *path;
f3ed775e 290
feb0f3e5 291 path = utils_get_home_dir();
cd9adb8b 292 if (path == nullptr) {
58a97671 293 ret = -1;
f3ed775e
DG
294 goto error;
295 }
296
297 /* Create default config file */
298 ret = create_config_file(path);
299 if (ret < 0) {
300 goto error;
301 }
302
58a97671
DG
303 ret = config_add_session_name(path, session_name);
304 if (ret < 0) {
305 goto error;
306 }
307
f3ed775e
DG
308 DBG("Init config session in %s", path);
309
310error:
311 return ret;
312}
This page took 0.104851 seconds and 4 git commands to generate.