1
0
mirror of https://github.com/anope/anope.git synced 2026-06-29 02:26:38 +02:00

Make config variables a lot more useful.

- Config variables now no longer conflict with regular values.

- Config variables can now be read from the environment.
  (e.g. ${env.USER}).

- Config variables can now be used as partial values
  (e.g. support@${network.domain})
This commit is contained in:
Sadie Powell
2025-03-09 13:57:20 +00:00
parent c98602bf19
commit badcf31499
12 changed files with 83 additions and 35 deletions
+51 -14
View File
@@ -939,24 +939,12 @@ void Conf::LoadConf(File &file)
}
Block *b = block_stack.top();
if (b)
Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << b->name << "' '" << itemname << "' set to '" << wordbuffer << "'";
/* Check defines */
for (int i = 0; i < this->CountBlock("define"); ++i)
{
const Block &define = this->GetBlock("define", i);
const Anope::string &dname = define.Get<const Anope::string>("name");
if (dname == wordbuffer && &define != b)
wordbuffer = define.Get<const Anope::string>("value");
Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << b->name << "' '" << itemname << "' set to '" << wordbuffer << "'";
b->items[itemname] = ReplaceVars(wordbuffer, file, linenumber);
}
if (b)
b->items[itemname] = wordbuffer;
wordbuffer.clear();
itemname.clear();
}
@@ -991,3 +979,52 @@ void Conf::LoadConf(File &file)
throw ConfigException("Unterminated commented block at end of file: " + file.GetName());
}
}
Anope::string Conf::ReplaceVars(const Anope::string &str, const File &file, int linenumber)
{
Anope::string ret;
for (auto it = str.begin(); it != str.end(); )
{
if (*it != '$')
{
ret.push_back(*it++);
continue;
}
if (++it == str.end() || *it != '{')
continue;
it++;
Anope::string var;
while (it != str.end() && *it != '}')
var.push_back(*it++);
if (it == str.end())
throw ConfigException("Unterminated variable: " + file.GetName() + ":" + Anope::ToString(linenumber));
it++;
if (var.compare(0, 4, "env.", 4) == 0)
{
// This is an environment variable rather than a defined variable
const char* envstr = getenv(var.c_str() + 4);
if (envstr && envstr)
ret.append(envstr);
continue;
}
for (int i = 0; i < this->CountBlock("define"); ++i)
{
const auto &define = this->GetBlock("define", i);
const auto defname = define.Get<const Anope::string>("name");
if (defname == var)
{
ret.append(define.Get<const Anope::string>("value"));
break;
}
}
}
if (!str.equals_cs(ret))
Log(LOG_DEBUG) << "Expanded \"" << str << "\" to \"" << ret << "\"";
return ret;
}