GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/options.cc
Date: 2024-04-28 02:33:07
Exec Total Coverage
Lines: 267 346 77.2%
Branches: 274 647 42.3%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 *
4 * Fills an internal map of key-value pairs from ASCII files in key=value
5 * style. Parameters can be overwritten. Used to read configuration from
6 * /etc/cvmfs/...
7 */
8
9 #include "cvmfs_config.h"
10 #include "options.h"
11
12 #include <fcntl.h>
13 #include <sys/wait.h>
14 #include <unistd.h>
15
16 #include <cassert>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <utility>
20
21 #include "sanitizer.h"
22 #include "util/exception.h"
23 #include "util/logging.h"
24 #include "util/posix.h"
25 #include "util/string.h"
26
27 using namespace std; // NOLINT
28
29 #ifdef CVMFS_NAMESPACE_GUARD
30 namespace CVMFS_NAMESPACE_GUARD {
31 #endif
32
33
34 472 static string EscapeShell(const std::string &raw) {
35
2/2
✓ Branch 1 taken 6935 times.
✓ Branch 2 taken 469 times.
7404 for (unsigned i = 0, l = raw.length(); i < l; ++i) {
36
6/6
✓ Branch 1 taken 6108 times.
✓ Branch 2 taken 827 times.
✓ Branch 4 taken 5297 times.
✓ Branch 5 taken 811 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 6932 times.
13059 if (!(((raw[i] >= '0') && (raw[i] <= '9')) ||
37
4/4
✓ Branch 1 taken 5275 times.
✓ Branch 2 taken 849 times.
✓ Branch 4 taken 4838 times.
✓ Branch 5 taken 437 times.
6124 ((raw[i] >= 'A') && (raw[i] <= 'Z')) ||
38
3/4
✓ Branch 1 taken 4508 times.
✓ Branch 2 taken 1179 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4508 times.
5687 ((raw[i] >= 'a') && (raw[i] <= 'z')) ||
39
6/6
✓ Branch 1 taken 632 times.
✓ Branch 2 taken 547 times.
✓ Branch 4 taken 612 times.
✓ Branch 5 taken 20 times.
✓ Branch 7 taken 341 times.
✓ Branch 8 taken 271 times.
1179 (raw[i] == '/') || (raw[i] == ':') || (raw[i] == '.') ||
40
5/6
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 330 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 8 times.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
341 (raw[i] == '_') || (raw[i] == '-') || (raw[i] == ',')))
41 {
42 3 goto escape_shell_quote;
43 }
44 }
45
1/2
✓ Branch 1 taken 469 times.
✗ Branch 2 not taken.
469 return raw;
46
47 3 escape_shell_quote:
48
1/2
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
6 string result = "'";
49
2/2
✓ Branch 1 taken 110 times.
✓ Branch 2 taken 3 times.
113 for (unsigned i = 0, l = raw.length(); i < l; ++i) {
50
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 110 times.
110 if (raw[i] == '\'')
51 result += "\\";
52
1/2
✓ Branch 2 taken 110 times.
✗ Branch 3 not taken.
110 result += raw[i];
53 }
54
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 result += "'";
55 3 return result;
56 }
57
58
59 304 string OptionsManager::TrimParameter(const string &parameter) {
60 304 string result = Trim(parameter);
61 // Strip "readonly"
62
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 304 times.
304 if (result.find("readonly ") == 0) {
63 result = result.substr(9);
64 result = Trim(result);
65
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 292 times.
304 } else if (result.find("export ") == 0) {
66
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 result = result.substr(7);
67
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 result = Trim(result);
68
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 292 times.
292 } else if (result.find("eval ") == 0) {
69 result = result.substr(5);
70 result = Trim(result);
71 }
72 304 return result;
73 }
74
75 340 string OptionsManager::SanitizeParameterAssignment(string *line,
76 vector <string> *tokens) {
77 340 size_t comment_idx = line->find("#");
78
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 316 times.
340 if (comment_idx != string::npos)
79
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 *line = line->substr(0, comment_idx);
80
1/2
✓ Branch 1 taken 340 times.
✗ Branch 2 not taken.
340 *line = Trim(*line);
81
2/2
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 316 times.
340 if (line->empty())
82
1/2
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
24 return "";
83
1/2
✓ Branch 1 taken 316 times.
✗ Branch 2 not taken.
316 *tokens = SplitString(*line, '=');
84
2/2
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 304 times.
316 if (tokens->size() < 2)
85
1/2
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 return "";
86
1/2
✓ Branch 2 taken 304 times.
✗ Branch 3 not taken.
304 string parameter = TrimParameter((*tokens)[0]);
87
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 304 times.
304 if (parameter.find(" ") != string::npos)
88 return "";
89 304 return parameter;
90 304 }
91
92 11 void OptionsManager::SwitchTemplateManager(
93 OptionsTemplateManager *opt_templ_mgr_param) {
94
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 delete opt_templ_mgr_;
95
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (opt_templ_mgr_param != NULL) {
96 11 opt_templ_mgr_ = opt_templ_mgr_param;
97 } else {
98 opt_templ_mgr_ = new OptionsTemplateManager();
99 }
100 11 for (std::map<std::string, std::string>::iterator it
101 11 = templatable_values_.begin();
102
2/2
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
15 it != templatable_values_.end();
103 4 it++) {
104
2/4
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 4 times.
✗ Branch 7 not taken.
4 config_[it->first].value = it->second;
105
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 opt_templ_mgr_->ParseString(&(config_[it->first].value));
106
2/4
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 4 times.
✗ Branch 6 not taken.
4 UpdateEnvironment(it->first, config_[it->first]);
107 }
108 11 }
109
110 9 bool SimpleOptionsParser::TryParsePath(const string &config_file) {
111
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 LogCvmfs(kLogCvmfs, kLogDebug, "Fast-parsing config file %s",
112 config_file.c_str());
113 9 string line;
114
1/2
✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
9 FILE *fconfig = fopen(config_file.c_str(), "r");
115
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
9 if (fconfig == NULL)
116 1 return false;
117
118 // Read line by line and extract parameters
119
3/4
✓ Branch 1 taken 124 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 116 times.
✓ Branch 4 taken 8 times.
124 while (GetLineFile(fconfig, &line)) {
120 116 vector <string> tokens;
121
1/2
✓ Branch 1 taken 116 times.
✗ Branch 2 not taken.
116 string parameter = SanitizeParameterAssignment(&line, &tokens);
122
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 86 times.
116 if (parameter.empty())
123 30 continue;
124
125 // Strip quotes from value
126
1/2
✓ Branch 3 taken 86 times.
✗ Branch 4 not taken.
86 tokens.erase(tokens.begin());
127
3/6
✓ Branch 2 taken 86 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 86 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 86 times.
✗ Branch 9 not taken.
172 string value = Trim(JoinStrings(tokens, "="));
128 86 unsigned value_length = value.length();
129
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 24 times.
86 if (value_length > 2) {
130
7/11
✓ Branch 1 taken 62 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 56 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 6 times.
✓ Branch 10 taken 12 times.
✓ Branch 11 taken 50 times.
118 if ( ((value[0] == '"') && ((value[value_length - 1] == '"'))) ||
131
5/9
✓ Branch 1 taken 56 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 50 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
56 ((value[0] == '\'') && ((value[value_length - 1] == '\''))) )
132 {
133
1/2
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
12 value = value.substr(1, value_length - 2);
134 }
135 }
136
137 86 ConfigValue config_value;
138
1/2
✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
86 config_value.source = config_file;
139
1/2
✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
86 config_value.value = value;
140
2/4
✓ Branch 1 taken 86 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 5 not taken.
86 PopulateParameter(parameter, config_value);
141
4/4
✓ Branch 3 taken 86 times.
✓ Branch 4 taken 30 times.
✓ Branch 6 taken 86 times.
✓ Branch 7 taken 30 times.
146 }
142
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
8 fclose(fconfig);
143 8 return true;
144 9 }
145
146 21 void BashOptionsManager::ParsePath(const string &config_file,
147 const bool external) {
148
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 LogCvmfs(kLogCvmfs, kLogDebug, "Parsing config file %s", config_file.c_str());
149 int retval;
150 int pipe_open[2];
151 int pipe_quit[2];
152 21 pid_t pid_child = 0;
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (external) {
154 // cvmfs can run in the process group of automount in which case
155 // autofs won't mount an additional config repository. We create a
156 // short-lived process that detaches from the process group and triggers
157 // autofs to mount the config repository, if necessary. It holds a file
158 // handle to the config file until the main process opened the file, too.
159 MakePipe(pipe_open);
160 MakePipe(pipe_quit);
161 switch (pid_child = fork()) {
162 case -1:
163 PANIC(NULL);
164 case 0: { // Child
165 close(pipe_open[0]);
166 close(pipe_quit[1]);
167 // If this is not a process group leader, create a new session
168 if (getpgrp() != getpid()) {
169 pid_t new_session = setsid();
170 assert(new_session != (pid_t)-1);
171 }
172 (void)open(config_file.c_str(), O_RDONLY);
173 char ready = 'R';
174 WritePipe(pipe_open[1], &ready, 1);
175 retval = read(pipe_quit[0], &ready, 1);
176 _exit(retval); // Don't flush shared file descriptors
177 }
178 }
179 // Parent
180 close(pipe_open[1]);
181 close(pipe_quit[0]);
182 char ready = 0;
183 ReadPipe(pipe_open[0], &ready, 1);
184 assert(ready == 'R');
185 close(pipe_open[0]);
186 }
187
1/2
✓ Branch 1 taken 21 times.
✗ Branch 2 not taken.
21 const string config_path = GetParentPath(config_file);
188
1/2
✓ Branch 2 taken 21 times.
✗ Branch 3 not taken.
21 FILE *fconfig = fopen(config_file.c_str(), "r");
189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 21 times.
21 if (pid_child > 0) {
190 char c = 'C';
191 WritePipe(pipe_quit[1], &c, 1);
192 int statloc;
193 waitpid(pid_child, &statloc, 0);
194 close(pipe_quit[1]);
195 }
196
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if (!fconfig) {
197
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
1 if (external && !DirectoryExists(config_path)) {
198 string repo_required;
199 if (GetValue("CVMFS_CONFIG_REPO_REQUIRED", &repo_required) &&
200 IsOn(repo_required)) {
201 LogCvmfs(kLogCvmfs, kLogStderr | kLogSyslogErr,
202 "required configuration repository directory does not exist: %s",
203 config_path.c_str());
204 // Do not crash as in abort(), which can trigger core file creation
205 // from the mount helper
206 exit(1);
207 }
208
209 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogWarn,
210 "configuration repository directory does not exist: %s",
211 config_path.c_str());
212 }
213 1 return;
214 }
215
216 int fd_stdin;
217 int fd_stdout;
218 int fd_stderr;
219
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 retval = Shell(&fd_stdin, &fd_stdout, &fd_stderr);
220
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20 times.
20 assert(retval);
221
222 // Let the shell read the file
223 40 string line;
224
1/2
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
40 const string newline = "\n";
225
5/15
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 20 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 20 times.
✗ Branch 15 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 20 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
40 const string cd = "cd \"" + ((config_path == "") ? "/" : config_path) + "\"" +
226
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
40 newline;
227
1/2
✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
20 WritePipe(fd_stdin, cd.data(), cd.length());
228
3/4
✓ Branch 1 taken 244 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
✓ Branch 4 taken 20 times.
244 while (GetLineFile(fconfig, &line)) {
229
1/2
✓ Branch 3 taken 224 times.
✗ Branch 4 not taken.
224 WritePipe(fd_stdin, line.data(), line.length());
230
1/2
✓ Branch 3 taken 224 times.
✗ Branch 4 not taken.
224 WritePipe(fd_stdin, newline.data(), newline.length());
231 }
232
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 rewind(fconfig);
233
234 // Read line by line and extract parameters
235
3/4
✓ Branch 1 taken 244 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 224 times.
✓ Branch 4 taken 20 times.
244 while (GetLineFile(fconfig, &line)) {
236 224 vector <string> tokens;
237
1/2
✓ Branch 1 taken 224 times.
✗ Branch 2 not taken.
224 string parameter = SanitizeParameterAssignment(&line, &tokens);
238
2/2
✓ Branch 1 taken 30 times.
✓ Branch 2 taken 194 times.
224 if (parameter.empty())
239 30 continue;
240
241 194 ConfigValue value;
242
1/2
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
194 value.source = config_file;
243
2/4
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 194 times.
✗ Branch 5 not taken.
194 const string sh_echo = "echo $" + parameter + "\n";
244
1/2
✓ Branch 3 taken 194 times.
✗ Branch 4 not taken.
194 WritePipe(fd_stdin, sh_echo.data(), sh_echo.length());
245
1/2
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
194 GetLineFd(fd_stdout, &value.value);
246
2/4
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 194 times.
✗ Branch 5 not taken.
194 PopulateParameter(parameter, value);
247
4/4
✓ Branch 3 taken 194 times.
✓ Branch 4 taken 30 times.
✓ Branch 6 taken 194 times.
✓ Branch 7 taken 30 times.
254 }
248
249
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 close(fd_stderr);
250
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 close(fd_stdout);
251
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 close(fd_stdin);
252
1/2
✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
20 fclose(fconfig);
253 }
254
255
256 39 bool OptionsManager::HasConfigRepository(const string &fqrn,
257 string *config_path) {
258 39 string cvmfs_mount_dir;
259
3/6
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 39 times.
39 if (!GetValue("CVMFS_MOUNT_DIR", &cvmfs_mount_dir)) {
260 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr, "CVMFS_MOUNT_DIR missing");
261 return false;
262 }
263
264 39 string config_repository;
265
4/6
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 39 times.
✗ Branch 6 not taken.
✓ Branch 9 taken 3 times.
✓ Branch 10 taken 36 times.
39 if (GetValue("CVMFS_CONFIG_REPOSITORY", &config_repository)) {
266
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 3 times.
3 if (config_repository.empty() || (config_repository == fqrn))
267 return false;
268
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 sanitizer::RepositorySanitizer repository_sanitizer;
269
2/4
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
3 if (!repository_sanitizer.IsValid(config_repository)) {
270 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr,
271 "invalid CVMFS_CONFIG_REPOSITORY: %s",
272 config_repository.c_str());
273 return false;
274 }
275
3/6
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
3 *config_path = cvmfs_mount_dir + "/" + config_repository + "/etc/cvmfs/";
276 3 return true;
277 3 }
278 36 return false;
279 39 }
280
281
282 void OptionsManager::ParseDefault(const string &fqrn) {
283 if (taint_environment_) {
284 int retval = setenv("CVMFS_FQRN", fqrn.c_str(), 1);
285 assert(retval == 0);
286 }
287
288 protected_parameters_.clear();
289 ParsePath("/etc/cvmfs/default.conf", false);
290 vector<string> dist_defaults =
291 FindFilesBySuffix("/etc/cvmfs/default.d", ".conf");
292 for (unsigned i = 0; i < dist_defaults.size(); ++i) {
293 ParsePath(dist_defaults[i], false);
294 }
295 ProtectParameter("CVMFS_CONFIG_REPOSITORY");
296 string external_config_path;
297 if ((fqrn != "") && HasConfigRepository(fqrn, &external_config_path))
298 ParsePath(external_config_path + "default.conf", true);
299 ParsePath("/etc/cvmfs/default.local", false);
300
301 if (fqrn != "") {
302 string domain;
303 vector<string> tokens = SplitString(fqrn, '.');
304 assert(tokens.size() > 1);
305 tokens.erase(tokens.begin());
306 domain = JoinStrings(tokens, ".");
307
308 if (HasConfigRepository(fqrn, &external_config_path))
309 ParsePath(external_config_path+ "domain.d/" + domain + ".conf",
310 true);
311 ParsePath("/etc/cvmfs/domain.d/" + domain + ".conf", false);
312 ParsePath("/etc/cvmfs/domain.d/" + domain + ".local", false);
313
314 if (HasConfigRepository(fqrn, &external_config_path))
315 ParsePath(external_config_path + "config.d/" + fqrn + ".conf", true);
316 ParsePath("/etc/cvmfs/config.d/" + fqrn + ".conf", false);
317 ParsePath("/etc/cvmfs/config.d/" + fqrn + ".local", false);
318 }
319 }
320
321
322 658 void OptionsManager::PopulateParameter(
323 const string &param,
324 ConfigValue val) {
325
1/2
✓ Branch 1 taken 658 times.
✗ Branch 2 not taken.
658 map<string, string>::const_iterator iter = protected_parameters_.find(param);
326
5/6
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 656 times.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 2 times.
✓ Branch 10 taken 656 times.
658 if ((iter != protected_parameters_.end()) && (iter->second != val.value)) {
327
1/3
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
4 LogCvmfs(kLogCvmfs, kLogDebug | kLogSyslogErr,
328 "error in cvmfs configuration: attempt to change protected %s "
329 "from %s to %s",
330 2 param.c_str(), iter->second.c_str(), val.value.c_str());
331 2 return;
332 }
333
2/4
✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 656 times.
✗ Branch 5 not taken.
656 ParseValue(param, &val);
334
2/4
✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 656 times.
✗ Branch 5 not taken.
656 config_[param] = val;
335
1/2
✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
656 UpdateEnvironment(param, val);
336 }
337
338 660 void OptionsManager::UpdateEnvironment(
339 const string &param,
340 ConfigValue val) {
341
2/2
✓ Branch 0 taken 543 times.
✓ Branch 1 taken 117 times.
660 if (taint_environment_) {
342 543 int retval = setenv(param.c_str(), val.value.c_str(), 1);
343
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 543 times.
543 assert(retval == 0);
344 }
345 660 }
346
347 656 void OptionsManager::ParseValue(std::string param, ConfigValue *val) {
348
1/2
✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
656 string orig = val->value;
349
1/2
✓ Branch 1 taken 656 times.
✗ Branch 2 not taken.
656 bool has_templ = opt_templ_mgr_->ParseString(&(val->value));
350
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 642 times.
656 if (has_templ) {
351
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 templatable_values_[param] = orig;
352 }
353 656 }
354
355
356 2 void OptionsManager::ProtectParameter(const string &param) {
357 2 string value;
358 // We don't care about the result. If param does not yet exists, we lock it
359 // to the empty string.
360
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 (void) GetValue(param, &value);
361
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 protected_parameters_[param] = value;
362 2 }
363
364
365 2 void OptionsManager::ClearConfig() {
366 2 config_.clear();
367 2 }
368
369
370 435 bool OptionsManager::IsDefined(const std::string &key) {
371
1/2
✓ Branch 1 taken 435 times.
✗ Branch 2 not taken.
435 map<string, ConfigValue>::const_iterator iter = config_.find(key);
372 435 return iter != config_.end();
373 }
374
375
376 4591 bool OptionsManager::GetValue(const string &key, string *value) const {
377
1/2
✓ Branch 1 taken 4591 times.
✗ Branch 2 not taken.
4591 map<string, ConfigValue>::const_iterator iter = config_.find(key);
378
2/2
✓ Branch 2 taken 1168 times.
✓ Branch 3 taken 3423 times.
4591 if (iter != config_.end()) {
379
1/2
✓ Branch 2 taken 1168 times.
✗ Branch 3 not taken.
1168 *value = iter->second.value;
380 1168 return true;
381 }
382
1/2
✓ Branch 1 taken 3423 times.
✗ Branch 2 not taken.
3423 *value = "";
383 3423 return false;
384 }
385
386
387 3 std::string OptionsManager::GetValueOrDie(const string &key) {
388 3 std::string value;
389
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
3 bool retval = GetValue(key, &value);
390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!retval) {
391 PANIC(kLogStderr | kLogDebug,
392 "%s configuration parameter missing", key.c_str());
393 }
394 3 return value;
395 }
396
397
398 484 bool OptionsManager::GetSource(const string &key, string *value) {
399
1/2
✓ Branch 1 taken 484 times.
✗ Branch 2 not taken.
484 map<string, ConfigValue>::const_iterator iter = config_.find(key);
400
1/2
✓ Branch 3 taken 484 times.
✗ Branch 4 not taken.
484 if (iter != config_.end()) {
401
1/2
✓ Branch 2 taken 484 times.
✗ Branch 3 not taken.
484 *value = iter->second.source;
402 484 return true;
403 }
404 *value = "";
405 return false;
406 }
407
408
409 91 bool OptionsManager::IsOn(const std::string &param_value) const {
410
1/2
✓ Branch 1 taken 91 times.
✗ Branch 2 not taken.
91 const string uppercase = ToUpper(param_value);
411
5/8
✓ Branch 1 taken 81 times.
✓ Branch 2 taken 10 times.
✓ Branch 4 taken 81 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 81 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 81 times.
172 return ((uppercase == "YES") || (uppercase == "ON") || (uppercase == "1") ||
412 172 (uppercase == "TRUE"));
413 91 }
414
415
416 bool OptionsManager::IsOff(const std::string &param_value) const {
417 const string uppercase = ToUpper(param_value);
418 return ((uppercase == "NO") || (uppercase == "OFF") || (uppercase == "0") ||
419 (uppercase == "FALSE"));
420 }
421
422
423 81 vector<string> OptionsManager::GetAllKeys() {
424 81 vector<string> result;
425 81 for (map<string, ConfigValue>::const_iterator i = config_.begin(),
426
2/2
✓ Branch 4 taken 500 times.
✓ Branch 5 taken 81 times.
581 iEnd = config_.end(); i != iEnd; ++i)
427 {
428
1/2
✓ Branch 2 taken 500 times.
✗ Branch 3 not taken.
500 result.push_back(i->first);
429 }
430 81 return result;
431 }
432
433
434 12 vector<string> OptionsManager::GetEnvironmentSubset(
435 const string &key_prefix,
436 bool strip_prefix)
437 {
438 12 vector<string> result;
439 12 for (map<string, ConfigValue>::const_iterator i = config_.begin(),
440
2/2
✓ Branch 4 taken 112 times.
✓ Branch 5 taken 12 times.
124 iEnd = config_.end(); i != iEnd; ++i)
441 {
442 112 const bool ignore_prefix = false;
443
3/4
✓ Branch 2 taken 112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14 times.
✓ Branch 5 taken 98 times.
112 if (HasPrefix(i->first, key_prefix, ignore_prefix)) {
444 const string output_key = strip_prefix
445 2 ? i->first.substr(key_prefix.length())
446
4/6
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 8 taken 12 times.
✗ Branch 9 not taken.
16 : i->first;
447
3/6
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 14 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 14 times.
✗ Branch 9 not taken.
14 result.push_back(output_key + "=" + i->second.value);
448 14 }
449 }
450 12 return result;
451 }
452
453
454 77 string OptionsManager::Dump() {
455 77 string result;
456
1/2
✓ Branch 1 taken 77 times.
✗ Branch 2 not taken.
77 vector<string> keys = GetAllKeys();
457
2/2
✓ Branch 1 taken 472 times.
✓ Branch 2 taken 77 times.
549 for (unsigned i = 0, l = keys.size(); i < l; ++i) {
458 bool retval;
459 472 string value;
460 472 string source;
461
462
1/2
✓ Branch 2 taken 472 times.
✗ Branch 3 not taken.
472 retval = GetValue(keys[i], &value);
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 472 times.
472 assert(retval);
464
1/2
✓ Branch 2 taken 472 times.
✗ Branch 3 not taken.
472 retval = GetSource(keys[i], &source);
465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 472 times.
472 assert(retval);
466
4/8
✓ Branch 1 taken 472 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 472 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 472 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 472 times.
✗ Branch 12 not taken.
944 result += keys[i] + "=" + EscapeShell(value) +
467
3/6
✓ Branch 1 taken 472 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 472 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 472 times.
✗ Branch 8 not taken.
472 " # from " + source + "\n";
468 472 }
469 154 return result;
470 77 }
471
472
473 378 void OptionsManager::SetValue(const string &key, const string &value) {
474 378 ConfigValue config_value;
475
1/2
✓ Branch 1 taken 378 times.
✗ Branch 2 not taken.
378 config_value.source = "@INTERNAL@";
476
1/2
✓ Branch 1 taken 378 times.
✗ Branch 2 not taken.
378 config_value.value = value;
477
2/4
✓ Branch 1 taken 378 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 378 times.
✗ Branch 5 not taken.
378 PopulateParameter(key, config_value);
478 378 }
479
480
481 21 void OptionsManager::UnsetValue(const string &key) {
482 21 protected_parameters_.erase(key);
483 21 config_.erase(key);
484
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 2 times.
21 if (taint_environment_)
485 19 unsetenv(key.c_str());
486 21 }
487
488 const char *DefaultOptionsTemplateManager
489 ::kTemplateIdentFqrn = "fqrn";
490
491 const char *DefaultOptionsTemplateManager
492 ::kTemplateIdentOrg = "org";
493
494 24 DefaultOptionsTemplateManager::DefaultOptionsTemplateManager(
495 24 std::string fqrn) {
496
3/6
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 24 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 24 times.
✗ Branch 9 not taken.
24 SetTemplate(kTemplateIdentFqrn, fqrn);
497
1/2
✓ Branch 1 taken 24 times.
✗ Branch 2 not taken.
24 vector<string> fqrn_parts = SplitString(fqrn, '.');
498
3/6
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 24 times.
✗ Branch 10 not taken.
24 SetTemplate(kTemplateIdentOrg, fqrn_parts[0]);
499 24 }
500
501 54 void OptionsTemplateManager::SetTemplate(std::string name, std::string val) {
502 54 templates_[name] = val;
503 54 }
504
505 58 std::string OptionsTemplateManager::GetTemplate(std::string name) {
506
2/2
✓ Branch 1 taken 14 times.
✓ Branch 2 taken 44 times.
58 if (templates_.count(name)) {
507 14 return templates_[name];
508 } else {
509
2/4
✓ Branch 1 taken 44 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44 times.
✗ Branch 5 not taken.
44 std::string var_name = "@" + name + "@";
510
1/2
✓ Branch 2 taken 44 times.
✗ Branch 3 not taken.
44 LogCvmfs(kLogCvmfs, kLogDebug, "Undeclared variable: %s",
511 var_name.c_str());
512 44 return var_name;
513 44 }
514 }
515
516 664 bool OptionsTemplateManager::ParseString(std::string *input) {
517 664 std::string result;
518
1/2
✓ Branch 1 taken 664 times.
✗ Branch 2 not taken.
664 std::string in = *input;
519 664 bool has_vars = false;
520 664 int mode = 0;
521 664 std::string stock;
522
2/2
✓ Branch 1 taken 15474 times.
✓ Branch 2 taken 664 times.
16138 for (std::string::size_type i = 0; i < in.size(); i++) {
523
2/3
✓ Branch 0 taken 15162 times.
✓ Branch 1 taken 312 times.
✗ Branch 2 not taken.
15474 switch (mode) {
524 15162 case 0:
525
3/4
✓ Branch 1 taken 15162 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 65 times.
✓ Branch 4 taken 15097 times.
15162 if (in[i] == '@') {
526 65 mode = 1;
527 } else {
528
2/4
✓ Branch 1 taken 15097 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15097 times.
✗ Branch 5 not taken.
15097 result += in[i];
529 }
530 15162 break;
531 312 case 1:
532
3/4
✓ Branch 1 taken 312 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 51 times.
✓ Branch 4 taken 261 times.
312 if (in[i] == '@') {
533 51 mode = 0;
534
3/6
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 51 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 51 times.
✗ Branch 8 not taken.
51 result += GetTemplate(stock);
535
1/2
✓ Branch 1 taken 51 times.
✗ Branch 2 not taken.
51 stock = "";
536 51 has_vars = true;
537 } else {
538
2/4
✓ Branch 1 taken 261 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 261 times.
✗ Branch 5 not taken.
261 stock += in[i];
539 }
540 312 break;
541 }
542 }
543
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 650 times.
664 if (mode == 1) {
544
2/4
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
14 result += "@" + stock;
545 }
546
1/2
✓ Branch 1 taken 664 times.
✗ Branch 2 not taken.
664 *input = result;
547 664 return has_vars;
548 664 }
549
550 7 bool OptionsTemplateManager::HasTemplate(std::string name) {
551 7 return templates_.count(name);
552 }
553
554 #ifdef CVMFS_NAMESPACE_GUARD
555 } // namespace CVMFS_NAMESPACE_GUARD
556 #endif
557