#include <fstream>
#include <regex>
+#include <unistd.h>
+#include <cstdio>
+#include <libgen.h>
#include "namespaces.hh"
#include "arguments.hh"
pdns::rust::settings::rec::merge(settings, data);
}
+static void convertACLFile(const string& includeDir, const string& apiDir, const std::string& filename)
+{
+ auto path = includeDir;
+ path.append("/").append(filename).append(".conf");
+ auto file = ifstream(path);
+ if (!file.is_open()) {
+ cerr << "Cannot open " << path << endl;
+ return;
+ }
+ rust::vec<rust::string> result;
+ std::string line;
+ while (getline(file, line)) {
+ auto pos = line.find('#');
+ if (pos != string::npos) {
+ line.resize(pos);
+ }
+ boost::trim(line);
+ if (line.empty()) {
+ continue;
+ }
+ auto plusis = line.find("+=");
+ if (plusis != string::npos) {
+ auto val = line.substr(plusis + 2);
+ boost::trim(val);
+ result.emplace_back(val);
+ }
+ }
+ rust::string yaml;
+ if (filename == "allow-from") {
+ yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_from", "allow_from_file", result);
+ }
+ else {
+ yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", result);
+ }
+ string yamlfilename = apiDir;
+ yamlfilename.append("/").append(filename).append(".yml");
+ ofstream ofconf(yamlfilename + ".tmp");
+ if (!ofconf) {
+ throw runtime_error("Could not open config file '" + yamlfilename + "' for writing: " + stringerror());
+ }
+ ofconf << "# Generated by pdns-recursor REST API, DO NOT EDIT" << endl;
+ ofconf << yaml << endl;
+ ofconf.close();
+ cerr << "Converted " << path << " to " << yamlfilename <<endl;
+ if (rename(path.c_str(), (path + ".converted").c_str()) != 0) {
+ // LOGGING
+ unlink(yamlfilename.c_str());
+ }
+ // ERROR CHECKS AND LOG
+ rename((yamlfilename + ".tmp").c_str(), yamlfilename.c_str());
+}
+
+static void convertForwardsandAuths(const std::string& includeDir, const std::string& apiDir, Logr::log_t log)
+{
+ std::vector<std::string> forwardFiles;
+ ::arg().gatherIncludes(includeDir, "..conf", forwardFiles);
+ pdns::rust::settings::rec::Recursorsettings settings;
+ for (const auto& file : forwardFiles) {
+ auto yaml = pdns::settings::rec::oldStyleSettingsFileToYaml(file, false);
+ cerr << "Converted YAML for " << file << endl;
+ cerr << yaml << endl;
+ pdns::rust::settings::rec::merge(settings, yaml);
+ }
+ const string yamlAPiZonesFile = apiDir + "/apizones";
+
+ for (auto& zone : settings.recursor.auth_zones) {
+ const std::string origName(zone.file);
+ std::string newName(zone.file);
+ newName.replace(0, includeDir.length(), apiDir);
+ cerr << "Rename " << origName << ' ' << newName << ' ';
+ auto ret = rename(origName.c_str(), newName.c_str());
+ cerr << ret << ' ' << stringerror() << endl;
+ zone.file = ::rust::String(newName);
+ api_add_auth_zone(yamlAPiZonesFile, zone);
+ }
+ for (const auto& zone : settings.recursor.forward_zones) {
+ api_add_forward_zone(yamlAPiZonesFile, zone);
+ }
+ for (const auto& zone : settings.recursor.forward_zones_recurse) {
+ api_add_forward_zone(yamlAPiZonesFile, zone);
+ }
+ for (const auto& file : forwardFiles) {
+ rename(file.c_str(), (file + ".converted").c_str());
+ }
+}
+
+void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, pdns::rust::settings::rec::Recursorsettings& settings, Logr::log_t log)
+{
+ auto apiDir = std::string(settings.webservice.api_dir);
+ if (apiDir.empty()) {
+ return;
+ }
+ auto includeDir = std::string(settings.recursor.include_dir);
+ if (!includeDirOnCommandLine.empty()) {
+ includeDir = includeDirOnCommandLine;
+ }
+ if (includeDir == apiDir) {
+ throw runtime_error("Active YAML settings do not allow include_dir to be equal to api_dir");
+ }
+ const std::array<std::string, 2> aclFiles = {
+ "allow-from",
+ "allow-notify-from"
+ };
+ for (const auto& file : aclFiles) {
+ convertACLFile(includeDir, apiDir, file);
+ auto path = apiDir;
+ path.append("/").append(file).append(".yml");
+ try {
+ mergeYamlSubFile(path, settings, log);
+ }
+ catch (const runtime_error& err) {
+ }
+ }
+ convertForwardsandAuths(includeDir, apiDir, log);
+}
+
pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, Recursorsettings& settings, std::string& msg, Logr::log_t log)
{
auto file = ifstream(configname);