29 #ifdef CVMFS_NAMESPACE_GUARD
30 namespace CVMFS_NAMESPACE_GUARD {
35 for (
unsigned i = 0, l = raw.length(); i < l; ++i) {
36 if (!(((raw[i] >=
'0') && (raw[i] <=
'9'))
37 || ((raw[i] >=
'A') && (raw[i] <=
'Z'))
38 || ((raw[i] >=
'a') && (raw[i] <=
'z')) || (raw[i] ==
'/')
39 || (raw[i] ==
':') || (raw[i] ==
'.') || (raw[i] ==
'_')
40 || (raw[i] ==
'-') || (raw[i] ==
','))) {
41 goto escape_shell_quote;
48 for (
unsigned i = 0, l = raw.length(); i < l; ++i) {
59 string result =
Trim(parameter);
61 if (result.find(
"readonly ") == 0) {
62 result = result.substr(9);
63 result =
Trim(result);
64 }
else if (result.find(
"export ") == 0) {
65 result = result.substr(7);
66 result =
Trim(result);
67 }
else if (result.find(
"eval ") == 0) {
68 result = result.substr(5);
69 result =
Trim(result);
75 vector<string> *tokens) {
76 size_t comment_idx = line->find(
"#");
77 if (comment_idx != string::npos)
78 *line = line->substr(0, comment_idx);
83 if (tokens->size() < 2)
85 string parameter = TrimParameter((*tokens)[0]);
86 if (parameter.find(
" ") != string::npos)
93 delete opt_templ_mgr_;
94 if (opt_templ_mgr_param != NULL) {
95 opt_templ_mgr_ = opt_templ_mgr_param;
99 for (std::map<std::string, std::string>::iterator it =
100 templatable_values_.begin();
101 it != templatable_values_.end();
103 config_[it->first].value = it->second;
104 opt_templ_mgr_->ParseString(&(config_[it->first].value));
105 UpdateEnvironment(it->first, config_[it->first]);
111 config_file.c_str());
113 FILE *fconfig = fopen(config_file.c_str(),
"r");
119 vector<string> tokens;
120 string parameter = SanitizeParameterAssignment(&line, &tokens);
121 if (parameter.empty())
125 tokens.erase(tokens.begin());
127 unsigned value_length = value.length();
128 if (value_length > 2) {
129 if (((value[0] ==
'"') && ((value[value_length - 1] ==
'"')))
130 || ((value[0] ==
'\'') && ((value[value_length - 1] ==
'\'')))) {
131 value = value.substr(1, value_length - 2);
136 config_value.
source = config_file;
137 config_value.
value = value;
138 PopulateParameter(parameter, config_value);
145 const bool external) {
159 switch (pid_child = fork()) {
166 if (getpgrp() != getpid()) {
167 pid_t new_session = setsid();
168 assert(new_session != (pid_t)-1);
170 (void)open(config_file.c_str(), O_RDONLY);
173 retval = read(pipe_quit[0], &ready, 1);
186 FILE *fconfig = fopen(config_file.c_str(),
"r");
191 waitpid(pid_child, &statloc, 0);
196 string repo_required;
197 if (GetValue(
"CVMFS_CONFIG_REPO_REQUIRED", &repo_required)
198 && IsOn(repo_required)) {
201 "required configuration repository directory does not exist: %s",
202 config_path.c_str());
209 "configuration repository directory does not exist: %s",
210 config_path.c_str());
218 retval =
Shell(&fd_stdin, &fd_stdout, &fd_stderr);
223 const string newline =
"\n";
224 const string cd =
"cd \"" + ((config_path ==
"") ?
"/" : config_path) +
"\""
226 WritePipe(fd_stdin, cd.data(), cd.length());
228 WritePipe(fd_stdin, line.data(), line.length());
229 WritePipe(fd_stdin, newline.data(), newline.length());
235 vector<string> tokens;
236 string parameter = SanitizeParameterAssignment(&line, &tokens);
237 if (parameter.empty())
241 value.
source = config_file;
242 const string sh_echo =
"echo $" + parameter +
"\n";
243 WritePipe(fd_stdin, sh_echo.data(), sh_echo.length());
245 PopulateParameter(parameter, value);
256 string *config_path) {
257 string cvmfs_mount_dir;
258 if (!GetValue(
"CVMFS_MOUNT_DIR", &cvmfs_mount_dir)) {
263 string config_repository;
264 if (GetValue(
"CVMFS_CONFIG_REPOSITORY", &config_repository)) {
265 if (config_repository.empty() || (config_repository == fqrn))
268 if (!repository_sanitizer.
IsValid(config_repository)) {
270 "invalid CVMFS_CONFIG_REPOSITORY: %s",
271 config_repository.c_str());
274 *config_path = cvmfs_mount_dir +
"/" + config_repository +
"/etc/cvmfs/";
282 if (taint_environment_) {
283 int retval = setenv(
"CVMFS_FQRN", fqrn.c_str(), 1);
287 protected_parameters_.clear();
288 ParsePath(
"/etc/cvmfs/default.conf",
false);
291 for (
unsigned i = 0; i < dist_defaults.size(); ++i) {
292 ParsePath(dist_defaults[i],
false);
294 ProtectParameter(
"CVMFS_CONFIG_REPOSITORY");
295 string external_config_path;
296 if ((fqrn !=
"") && HasConfigRepository(fqrn, &external_config_path))
297 ParsePath(external_config_path +
"default.conf",
true);
298 ParsePath(
"/etc/cvmfs/default.local",
false);
303 assert(tokens.size() > 1);
304 tokens.erase(tokens.begin());
307 if (HasConfigRepository(fqrn, &external_config_path))
308 ParsePath(external_config_path +
"domain.d/" + domain +
".conf",
true);
309 ParsePath(
"/etc/cvmfs/domain.d/" + domain +
".conf",
false);
310 ParsePath(
"/etc/cvmfs/domain.d/" + domain +
".local",
false);
312 if (HasConfigRepository(fqrn, &external_config_path))
313 ParsePath(external_config_path +
"config.d/" + fqrn +
".conf",
true);
314 ParsePath(
"/etc/cvmfs/config.d/" + fqrn +
".conf",
false);
315 ParsePath(
"/etc/cvmfs/config.d/" + fqrn +
".local",
false);
321 map<string, string>::const_iterator iter = protected_parameters_.find(param);
322 if ((iter != protected_parameters_.end()) && (iter->second != val.
value)) {
324 "error in cvmfs configuration: attempt to change protected %s "
326 param.c_str(), iter->second.c_str(), val.
value.c_str());
329 ParseValue(param, &val);
330 config_[param] = val;
331 UpdateEnvironment(param, val);
335 if (taint_environment_) {
336 int retval = setenv(param.c_str(), val.
value.c_str(), 1);
342 string orig = val->
value;
343 bool has_templ = opt_templ_mgr_->ParseString(&(val->
value));
345 templatable_values_[param] = orig;
354 (void)GetValue(param, &value);
355 protected_parameters_[param] = value;
363 map<string, ConfigValue>::const_iterator iter = config_.find(key);
364 return iter != config_.end();
369 map<string, ConfigValue>::const_iterator iter = config_.find(key);
370 if (iter != config_.end()) {
371 *value = iter->second.value;
381 bool retval = GetValue(key, &value);
391 map<string, ConfigValue>::const_iterator iter = config_.find(key);
392 if (iter != config_.end()) {
393 *value = iter->second.source;
402 const string uppercase =
ToUpper(param_value);
403 return ((uppercase ==
"YES") || (uppercase ==
"ON") || (uppercase ==
"1")
404 || (uppercase ==
"TRUE"));
409 const string uppercase =
ToUpper(param_value);
410 return ((uppercase ==
"NO") || (uppercase ==
"OFF") || (uppercase ==
"0")
411 || (uppercase ==
"FALSE"));
416 vector<string> result;
417 for (map<string, ConfigValue>::const_iterator i = config_.begin(),
418 iEnd = config_.end();
421 result.push_back(i->first);
429 vector<string> result;
430 for (map<string, ConfigValue>::const_iterator i = config_.begin(),
431 iEnd = config_.end();
434 const bool ignore_prefix =
false;
435 if (
HasPrefix(i->first, key_prefix, ignore_prefix)) {
436 const string output_key = strip_prefix
437 ? i->first.substr(key_prefix.length())
439 result.push_back(output_key +
"=" + i->second.value);
448 vector<string> keys = GetAllKeys();
449 for (
unsigned i = 0, l = keys.size(); i < l; ++i) {
454 retval = GetValue(keys[i], &value);
456 retval = GetSource(keys[i], &source);
458 result += keys[i] +
"=" +
EscapeShell(value) +
" # from " + source
466 config_value.
source =
"cvmfs_talk";
467 config_value.
value = value;
468 PopulateParameter(key, config_value);
473 config_value.
source =
"@INTERNAL@";
474 config_value.
value = value;
475 PopulateParameter(key, config_value);
480 protected_parameters_.erase(key);
482 if (taint_environment_)
483 unsetenv(key.c_str());
491 SetTemplate(kTemplateIdentFqrn, fqrn);
492 vector<string> fqrn_parts =
SplitString(fqrn,
'.');
493 SetTemplate(kTemplateIdentOrg, fqrn_parts[0]);
497 templates_[name] = val;
501 if (templates_.count(name)) {
502 return templates_[name];
504 std::string var_name =
"@" + name +
"@";
512 std::string in = *input;
513 bool has_vars =
false;
516 for (std::string::size_type i = 0; i < in.size(); i++) {
528 result += GetTemplate(stock);
538 result +=
"@" + stock;
545 return templates_.count(name);
548 #ifdef CVMFS_NAMESPACE_GUARD
std::string GetValueOrDie(const std::string &key)
std::string GetTemplate(std::string name)
static const char * kTemplateIdentOrg
static const char * kTemplateIdentFqrn
string Trim(const string &raw, bool trim_newline)
CVMFS_EXPORT const LogSource source
bool GetSource(const std::string &key, std::string *value)
string JoinStrings(const vector< string > &strings, const string &joint)
static string EscapeShell(const std::string &raw)
DefaultOptionsTemplateManager(std::string fqrn)
bool Shell(int *fd_stdin, int *fd_stdout, int *fd_stderr)
bool IsOn(const std::string ¶m_value) const
std::vector< std::string > GetEnvironmentSubset(const std::string &key_prefix, bool strip_prefix)
void PopulateParameter(const std::string ¶m, const ConfigValue val)
std::string SanitizeParameterAssignment(std::string *line, std::vector< std::string > *tokens)
assert((mem||(size==0))&&"Out Of Memory")
bool IsOff(const std::string ¶m_value) const
void ParseDefault(const std::string &fqrn)
bool HasConfigRepository(const std::string &fqrn, std::string *config_path)
void MakePipe(int pipe_fd[2])
void SwitchTemplateManager(OptionsTemplateManager *opt_templ_mgr_param)
void SetValue(const std::string &key, const std::string &value)
bool GetLineFile(FILE *f, std::string *line)
string ToUpper(const string &mixed_case)
bool TryParsePath(const std::string &config_file)
vector< string > SplitString(const string &str, char delim)
void SetValueFromTalk(const std::string &key, const std::string &value)
std::vector< std::string > GetAllKeys()
void ParseValue(const std::string param, ConfigValue *val)
bool HasPrefix(const string &str, const string &prefix, const bool ignore_case)
bool GetValue(const std::string &key, std::string *value) const
bool DirectoryExists(const std::string &path)
std::string TrimParameter(const std::string ¶meter)
void ParsePath(const std::string &config_file, const bool external)
bool GetLineFd(const int fd, std::string *line)
void SetTemplate(std::string name, std::string val)
void UpdateEnvironment(const std::string ¶m, ConfigValue val)
bool ParseString(std::string *input)
PathString GetParentPath(const PathString &path)
bool IsDefined(const std::string &key)
void WritePipe(int fd, const void *buf, size_t nbyte)
void ReadPipe(int fd, void *buf, size_t nbyte)
std::vector< std::string > FindFilesBySuffix(const std::string &dir, const std::string &suffix)
void ProtectParameter(const std::string ¶m)
void UnsetValue(const std::string &key)
bool HasTemplate(std::string name)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)