GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/options.h
Date: 2025-06-22 02:36:02
Exec Total Coverage
Lines: 22 22 100.0%
Branches: 9 16 56.2%

Line Branch Exec Source
1 /**
2 * This file is part of the CernVM File System.
3 */
4
5 #ifndef CVMFS_OPTIONS_H_
6 #define CVMFS_OPTIONS_H_
7
8 #include <stdint.h>
9
10 #include <cassert>
11 #include <map>
12 #include <string>
13 #include <vector>
14
15 #ifdef CVMFS_NAMESPACE_GUARD
16 namespace CVMFS_NAMESPACE_GUARD {
17 #endif
18
19 /**
20 * Templating manager used for variable replacement in the config file
21 */
22 class OptionsTemplateManager {
23 public:
24 void SetTemplate(std::string name, std::string val);
25 std::string GetTemplate(std::string name);
26 bool HasTemplate(std::string name);
27 bool ParseString(std::string *input);
28
29 private:
30 std::map<std::string, std::string> templates_;
31 };
32
33 class DefaultOptionsTemplateManager : public OptionsTemplateManager {
34 public:
35 explicit DefaultOptionsTemplateManager(std::string fqrn);
36
37 private:
38 static const char *kTemplateIdentFqrn;
39 static const char *kTemplateIdentOrg;
40 };
41
42 /**
43 * This is the abstract base class for the different option parsers. It parses
44 * and stores the information contained in different config files, keeping
45 * the last parsed file that changed each property. It stores the information
46 * in a key-value map so that for each variable name the value and last source
47 * are stored, and makes each property part of the program's environments
48 */
49 class OptionsManager {
50 public:
51 3245 explicit OptionsManager(OptionsTemplateManager *opt_templ_mgr_param)
52 3245 : taint_environment_(true) {
53
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 3077 times.
3245 if (opt_templ_mgr_param != NULL) {
54 168 opt_templ_mgr_ = opt_templ_mgr_param;
55 } else {
56
1/2
✓ Branch 1 taken 3077 times.
✗ Branch 2 not taken.
3077 opt_templ_mgr_ = new OptionsTemplateManager();
57 }
58 3245 }
59
60 96 OptionsManager(const OptionsManager &opt_mgr) {
61
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 config_ = opt_mgr.config_;
62
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 protected_parameters_ = opt_mgr.protected_parameters_;
63
1/2
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
96 templatable_values_ = opt_mgr.templatable_values_;
64 96 taint_environment_ = opt_mgr.taint_environment_;
65
66
2/4
✓ Branch 1 taken 96 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 96 times.
✗ Branch 5 not taken.
96 opt_templ_mgr_ = new OptionsTemplateManager(*(opt_mgr.opt_templ_mgr_));
67 96 }
68
69
1/2
✓ Branch 0 taken 3338 times.
✗ Branch 1 not taken.
6676 virtual ~OptionsManager() { delete opt_templ_mgr_; }
70
71 /**
72 * Switches the Options Templating Manager and reparses the set options
73 */
74 void SwitchTemplateManager(OptionsTemplateManager *opt_templ_mgr_param);
75
76 /**
77 * Opens the config_file and extracts all contained variables and their
78 * corresponding values. The new variables are set (and overwritten in case
79 * they were previously defined) as environment variables
80 *
81 * @param config_file absolute path to the configuration file
82 * @param external if true it indicates the configuration file is in the
83 * repository. If false the configuration file is in /etc
84 */
85 virtual void ParsePath(const std::string &config_file,
86 const bool external) = 0;
87
88 /**
89 * Parses the default config files for cvmfs
90 */
91 void ParseDefault(const std::string &fqrn);
92
93 /**
94 * Cleans all information about the variables
95 */
96 void ClearConfig();
97
98 /**
99 * Checks if a concrete key (variable) is defined
100 *
101 * @param key variable to be checked in the map
102 * @return true if there is a value for key, false otherwise
103 */
104 bool IsDefined(const std::string &key);
105
106 /**
107 * Gets the stored value for a concrete variable
108 *
109 * @param key variable to be accessed in the map
110 * @param value container of the received value, if it exists
111 * @return true if there was a value stored in the map for key
112 */
113 bool GetValue(const std::string &key, std::string *value) const;
114
115 /**
116 * Gets the stored value for a concrete variable. Panics if the value is
117 * missing.
118 *
119 * @param key variable to be accessed in the map
120 * @param value container of the received value, if it exists
121 */
122 std::string GetValueOrDie(const std::string &key);
123
124 /**
125 * Gets the stored last source of a concrete variable
126 *
127 * @param key variable to be accessed in the map
128 * @param value container of the received value, if it exists
129 * @return true if that variable was previously defined in
130 * at least one source
131 */
132 bool GetSource(const std::string &key, std::string *value);
133
134 /**
135 * Checks if a variable contains a boolean value
136 *
137 * @param param_value variable to be accessed in the map
138 * @return true if param has as value "YES", "ON" or "1". False otherwise
139 */
140 bool IsOn(const std::string &param_value) const;
141
142 /**
143 * Checks if a variable contains a boolean value
144 *
145 * @param param_value variable to be accessed in the map
146 * @return true if param has as value "NO", "OFF", "0", or "FALSE".
147 */
148 bool IsOff(const std::string &param_value) const;
149
150 /**
151 * Retrieves a vector containing all stored keys
152 *
153 * @return a vector with all keys contained in the map
154 */
155 std::vector<std::string> GetAllKeys();
156
157 /**
158 * Returns key=value strings from the options array for all keys that match
159 * key_prefix. Can be used to construct an environment pointer for execve.
160 */
161 std::vector<std::string> GetEnvironmentSubset(const std::string &key_prefix,
162 bool strip_prefix);
163
164 /**
165 * Gets all stored key-values of the map in an string format. This format
166 * follows the following pattern:
167 *
168 * "KEY=VALUE # from SOURCE"
169 *
170 * @return a vector containing all key-values in a string format
171 */
172 std::string Dump();
173
174 bool HasConfigRepository(const std::string &fqrn, std::string *config_path);
175
176 /**
177 * Similar to a bash "read-only" parameter: the current value will be locked
178 * and cannot be changed anymore by succeeding parsings of config files.
179 */
180 void ProtectParameter(const std::string &param);
181
182 /**
183 * Artificially inject values in the option manager.
184 */
185 void SetValue(const std::string &key, const std::string &value);
186
187 /**
188 * Artificially inject values in the option manager, marking
189 cvmfs_talk as the source.
190 */
191 void SetValueFromTalk(const std::string &key, const std::string &value);
192
193 /**
194 * Purge a value from the parameter map. Used in unit tests.
195 */
196 void UnsetValue(const std::string &key);
197
198 933 void set_taint_environment(bool value) { taint_environment_ = value; }
199
200 protected:
201 /**
202 * The ConfigValue structure contains a concrete value of a variable, as well
203 * as the source (complete path) of the config file where it was obtained
204 */
205 struct ConfigValue {
206 std::string value;
207 std::string source;
208 };
209
210 std::string TrimParameter(const std::string &parameter);
211 std::string SanitizeParameterAssignment(std::string *line,
212 std::vector<std::string> *tokens);
213 void PopulateParameter(const std::string &param, const ConfigValue val);
214 void ParseValue(const std::string param, ConfigValue *val);
215 void UpdateEnvironment(const std::string &param, ConfigValue val);
216 std::map<std::string, ConfigValue> config_;
217 std::map<std::string, std::string> protected_parameters_;
218 std::map<std::string, std::string> templatable_values_;
219
220 OptionsTemplateManager *opt_templ_mgr_;
221 /**
222 * Whether to add environment variables to the process' environment or not.
223 * In libcvmfs, we don't want a tainted environment.
224 */
225 bool taint_environment_;
226
227 private:
228 // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
229 OptionsManager &operator=(const OptionsManager & /* other */) {
230 assert(false);
231 }
232 }; // class OptionManager
233
234
235 /**
236 * Derived class from OptionsManager. This class provides a so-called fast
237 * parsing procedure which does not create a fork of the process and only
238 * retrieves those options of the configuration file which strictly are in the
239 * following format:
240 *
241 * "KEY=VALUE".
242 *
243 * No comments (#) are allowed.
244 *
245 * @note In order to use this parse it is necessary to execute the program
246 * with the "-o simple_options_parsing" flag
247 * @note If using IgProf profiling tool it is necessary to use this parser in
248 * order to avoid a fork
249 */
250 class SimpleOptionsParser : public OptionsManager {
251 public:
252 2993 explicit SimpleOptionsParser(
253 OptionsTemplateManager *opt_templ_mgr_param = NULL)
254 2993 : OptionsManager(opt_templ_mgr_param) { }
255 18 virtual void ParsePath(const std::string &config_file,
256 const bool external __attribute__((unused))) {
257 18 (void)TryParsePath(config_file);
258 18 }
259 // Libcvmfs returns success or failure, the fuse module fails silently
260 bool TryParsePath(const std::string &config_file);
261 }; // class SimpleOptionsManager
262
263
264 /**
265 * Derived class from OptionsManager. This class provides the
266 * complete parsing of the configuration files. In order to parse the
267 * configuration files it retrieves the "KEY=VALUE" pairs and uses bash for
268 * the rest, so that you can execute slightly complex scripts
269 */
270 class BashOptionsManager : public OptionsManager {
271 public:
272 252 explicit BashOptionsManager(
273 OptionsTemplateManager *opt_templ_mgr_param = NULL)
274 252 : OptionsManager(opt_templ_mgr_param) { }
275 void ParsePath(const std::string &config_file, const bool external);
276 }; // class BashOptionsManager
277
278
279 #ifdef CVMFS_NAMESPACE_GUARD
280 } // namespace CVMFS_NAMESPACE_GUARD
281 #endif
282
283 #endif // CVMFS_OPTIONS_H_
284