GCC Code Coverage Report


Directory: cvmfs/
File: cvmfs/options.h
Date: 2024-04-21 02:33:16
Exec Total Coverage
Lines: 23 23 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 private:
29 std::map<std::string, std::string> templates_;
30 };
31
32 class DefaultOptionsTemplateManager : public OptionsTemplateManager {
33 public:
34 explicit DefaultOptionsTemplateManager(std::string fqrn);
35 private:
36 static const char *kTemplateIdentFqrn;
37 static const char *kTemplateIdentOrg;
38 };
39
40 /**
41 * This is the abstract base class for the different option parsers. It parses
42 * and stores the information contained in different config files, keeping
43 * the last parsed file that changed each property. It stores the information
44 * in a key-value map so that for each variable name the value and last source
45 * are stored, and makes each property part of the program's environments
46 */
47 class OptionsManager {
48 public:
49 97 explicit OptionsManager(OptionsTemplateManager *opt_templ_mgr_param)
50 97 : taint_environment_(true) {
51
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 85 times.
97 if (opt_templ_mgr_param != NULL) {
52 12 opt_templ_mgr_ = opt_templ_mgr_param;
53 } else {
54
1/2
✓ Branch 1 taken 85 times.
✗ Branch 2 not taken.
85 opt_templ_mgr_ = new OptionsTemplateManager();
55 }
56 97 }
57
58 2 OptionsManager(const OptionsManager& opt_mgr) {
59
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 config_ = opt_mgr.config_;
60
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 protected_parameters_ = opt_mgr.protected_parameters_;
61
1/2
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
2 templatable_values_ = opt_mgr.templatable_values_;
62 2 taint_environment_ = opt_mgr.taint_environment_;
63
64
2/4
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 opt_templ_mgr_ = new OptionsTemplateManager(*(opt_mgr.opt_templ_mgr_));
65 2 }
66
67 196 virtual ~OptionsManager() {
68
1/2
✓ Branch 0 taken 98 times.
✗ Branch 1 not taken.
196 delete opt_templ_mgr_;
69 }
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(
162 const std::string &key_prefix,
163 bool strip_prefix);
164
165 /**
166 * Gets all stored key-values of the map in an string format. This format
167 * follows the following pattern:
168 *
169 * "KEY=VALUE # from SOURCE"
170 *
171 * @return a vector containing all key-values in a string format
172 */
173 std::string Dump();
174
175 bool HasConfigRepository(const std::string &fqrn, std::string *config_path);
176
177 /**
178 * Similar to a bash "read-only" parameter: the current value will be locked
179 * and cannot be changed anymore by succeeding parsings of config files.
180 */
181 void ProtectParameter(const std::string &param);
182
183 /**
184 * Artificially inject values in the option manager.
185 */
186 void SetValue(const std::string &key, const std::string &value);
187
188 /**
189 * Purge a value from the parameter map. Used in unit tests.
190 */
191 void UnsetValue(const std::string &key);
192
193 23 void set_taint_environment(bool value) { taint_environment_ = value; }
194
195 protected:
196 /**
197 * The ConfigValue structure contains a concrete value of a variable, as well
198 * as the source (complete path) of the config file where it was obtained
199 */
200 struct ConfigValue {
201 std::string value;
202 std::string source;
203 };
204
205 std::string TrimParameter(const std::string &parameter);
206 std::string SanitizeParameterAssignment(std::string *line,
207 std::vector <std::string> *tokens);
208 void PopulateParameter(const std::string &param, const ConfigValue val);
209 void ParseValue(const std::string param, ConfigValue *val);
210 void UpdateEnvironment(
211 const std::string &param, ConfigValue val);
212 std::map<std::string, ConfigValue> config_;
213 std::map<std::string, std::string> protected_parameters_;
214 std::map<std::string, std::string> templatable_values_;
215
216 OptionsTemplateManager *opt_templ_mgr_;
217 /**
218 * Whether to add environment variables to the process' environment or not.
219 * In libcvmfs, we don't want a tainted environment.
220 */
221 bool taint_environment_;
222
223 private:
224 // NOLINTNEXTLINE(bugprone-unhandled-self-assignment,cert-oop54-cpp)
225 OptionsManager & operator= (const OptionsManager & /* other */) {
226 assert(false);
227 }
228 }; // class OptionManager
229
230
231 /**
232 * Derived class from OptionsManager. This class provides a so-called fast
233 * parsing procedure which does not create a fork of the process and only
234 * retrieves those options of the configuration file which strictly are in the
235 * following format:
236 *
237 * "KEY=VALUE".
238 *
239 * No comments (#) are allowed.
240 *
241 * @note In order to use this parse it is necessary to execute the program
242 * with the "-o simple_options_parsing" flag
243 * @note If using IgProf profiling tool it is necessary to use this parser in
244 * order to avoid a fork
245 */
246 class SimpleOptionsParser : public OptionsManager {
247 public:
248 79 explicit SimpleOptionsParser(
249 OptionsTemplateManager *opt_templ_mgr_param = NULL)
250 79 : OptionsManager(opt_templ_mgr_param) { }
251 9 virtual void ParsePath(
252 const std::string &config_file,
253 const bool external __attribute__((unused))) {
254 9 (void) TryParsePath(config_file);
255 9 }
256 // Libcvmfs returns success or failure, the fuse module fails silently
257 bool TryParsePath(const std::string &config_file);
258 }; // class SimpleOptionsManager
259
260
261 /**
262 * Derived class from OptionsManager. This class provides the
263 * complete parsing of the configuration files. In order to parse the
264 * configuration files it retrieves the "KEY=VALUE" pairs and uses bash for
265 * the rest, so that you can execute slightly complex scripts
266 */
267 class BashOptionsManager : public OptionsManager {
268 public:
269 18 explicit BashOptionsManager(
270 OptionsTemplateManager *opt_templ_mgr_param = NULL)
271 18 : OptionsManager(opt_templ_mgr_param) { }
272 void ParsePath(const std::string &config_file, const bool external);
273 }; // class BashOptionsManager
274
275
276
277 #ifdef CVMFS_NAMESPACE_GUARD
278 } // namespace CVMFS_NAMESPACE_GUARD
279 #endif
280
281 #endif // CVMFS_OPTIONS_H_
282