GCC Code Coverage Report
Directory: cvmfs/ Exec Total Coverage
File: cvmfs/options.h Lines: 27 27 100.0 %
Date: 2019-02-03 02:48:13 Branches: 6 12 50.0 %

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
622
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
4
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
272
  explicit OptionsManager(OptionsTemplateManager *opt_templ_mgr_param)
50
272
      : taint_environment_(true) {
51
272
    if (opt_templ_mgr_param != NULL) {
52
99
      opt_templ_mgr_ = opt_templ_mgr_param;
53
    } else {
54
173
      opt_templ_mgr_ = new OptionsTemplateManager();
55
    }
56
  }
57
58
3
  OptionsManager(const OptionsManager& opt_mgr) {
59
3
    config_ = opt_mgr.config_;
60
3
    protected_parameters_ = opt_mgr.protected_parameters_;
61
3
    templatable_values_ = opt_mgr.templatable_values_;
62
3
    taint_environment_ = opt_mgr.taint_environment_;
63
64
3
    opt_templ_mgr_ = new OptionsTemplateManager(*(opt_mgr.opt_templ_mgr_));
65
3
  }
66
67
271
  virtual ~OptionsManager() {
68
271
    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);
114
115
  /**
116
   * Gets the stored last source of a concrete variable
117
   *
118
   * @param  key variable to be accessed in the map
119
   * @param  value container of the received value, if it exists
120
   * @return true if that variable was previously defined in
121
   *         at least one source
122
   */
123
  bool GetSource(const std::string &key, std::string *value);
124
125
  /**
126
   * Checks if a variable contains a boolean value
127
   *
128
   * @param   param_value variable to be accessed in the map
129
   * @return  true if param has as value "YES", "ON" or "1". False otherwise
130
   */
131
  bool IsOn(const std::string &param_value);
132
133
  /**
134
   * Retrieves a vector containing all stored keys
135
   *
136
   * @return a vector with all keys contained in the map
137
   */
138
  std::vector<std::string> GetAllKeys();
139
140
  /**
141
   * Returns key=value strings from the options array for all keys that match
142
   * key_prefix.  Can be used to construct an environment pointer for execve.
143
   */
144
  std::vector<std::string> GetEnvironmentSubset(
145
    const std::string &key_prefix,
146
    bool strip_prefix);
147
148
  /**
149
   * Gets all stored key-values of the map in an string format. This format
150
   * follows the following pattern:
151
   *
152
   * "KEY=VALUE    # from SOURCE"
153
   *
154
   * @return a vector containing all key-values in a string format
155
   */
156
  std::string Dump();
157
158
  bool HasConfigRepository(const std::string &fqrn, std::string *config_path);
159
160
  /**
161
   * Similar to a bash "read-only" parameter: the current value will be locked
162
   * and cannot be changed anymore by succeeding parsings of config files.
163
   */
164
  void ProtectParameter(const std::string &param);
165
166
  /**
167
   * Artificially inject values in the option manager.
168
   */
169
  void SetValue(const std::string &key, const std::string &value);
170
171
  /**
172
   * Purge a value from the parameter map.  Used in unit tests.
173
   */
174
  void UnsetValue(const std::string &key);
175
176
23
  void set_taint_environment(bool value) { taint_environment_ = value; }
177
178
 protected:
179
  /**
180
    * The ConfigValue structure contains a concrete value of a variable, as well
181
    * as the source (complete path) of the config file where it was obtained
182
    */
183
20729
  struct ConfigValue {
184
    std::string value;
185
    std::string source;
186
  };
187
188
  std::string TrimParameter(const std::string &parameter);
189
  void PopulateParameter(const std::string &param, const ConfigValue val);
190
  void ParseValue(const std::string param, ConfigValue *val);
191
  void UpdateEnvironment(
192
    const std::string &param, ConfigValue val);
193
  std::map<std::string, ConfigValue> config_;
194
  std::map<std::string, std::string> protected_parameters_;
195
  std::map<std::string, std::string> templatable_values_;
196
197
  OptionsTemplateManager *opt_templ_mgr_;
198
  /**
199
   * Whether to add environment variables to the process' environment or not.
200
   * In libcvmfs, we don't want a tainted environment.
201
   */
202
  bool taint_environment_;
203
204
 private:
205
  OptionsManager & operator= (const OptionsManager & other) {
206
    assert(false);
207
  }
208
};  // class OptionManager
209
210
211
/**
212
 * Derived class from OptionsManager. This class provides a so-called fast
213
 * parsing procedure which does not create a fork of the process and only
214
 * retrieves those options of the configuration file which strictly are in the
215
 * following format:
216
 *
217
 *  "KEY=VALUE".
218
 *
219
 *  No comments (#) are allowed.
220
 *
221
 *  @note In order to use this parse it is necessary to execute the program
222
 *        with the "-o simple_options_parsing" flag
223
 *  @note If using IgProf profiling tool it is necessary to use this parser in
224
 *        order to avoid a fork
225
 */
226
192
class SimpleOptionsParser : public OptionsManager {
227
 public:
228
167
  explicit SimpleOptionsParser(
229
    OptionsTemplateManager *opt_templ_mgr_param = NULL)
230
167
    : OptionsManager(opt_templ_mgr_param) { }
231
9
  virtual void ParsePath(
232
    const std::string &config_file,
233
    const bool external __attribute__((unused))) {
234
9
    (void) TryParsePath(config_file);
235
9
  }
236
  // Libcvmfs returns success or failure, the fuse module fails silently
237
  bool TryParsePath(const std::string &config_file);
238
};  // class SimpleOptionsManager
239
240
241
/**
242
 * Derived class from OptionsManager. This class provides the
243
 * complete parsing of the configuration files. In order to parse the
244
 * configuration files it retrieves the "KEY=VALUE" pairs and uses bash for
245
 * the rest, so that you can execute sightly complex scripts
246
 */
247
105
class BashOptionsManager : public OptionsManager {
248
 public:
249
105
  explicit BashOptionsManager(
250
    OptionsTemplateManager *opt_templ_mgr_param = NULL)
251
105
    : OptionsManager(opt_templ_mgr_param) { }
252
  void ParsePath(const std::string &config_file, const bool external);
253
};  // class BashOptionsManager
254
255
256
257
#ifdef CVMFS_NAMESPACE_GUARD
258
}  // namespace CVMFS_NAMESPACE_GUARD
259
#endif
260
261
#endif  // CVMFS_OPTIONS_H_