#include "ueberbackend.hh"
-AuthLua4::AuthLua4() { prepareContext(); }
-
LuaContext* AuthLua4::getLua()
{
return d_lw.get();
d_lw->registerFunction<DNSName(UpdatePolicyQuery::*)()>("getTsigName", [](UpdatePolicyQuery& upq) { return upq.tsigName; });
d_lw->registerFunction<std::string(UpdatePolicyQuery::*)()>("getPeerPrincipal", [](UpdatePolicyQuery& upq) { return upq.peerPrincipal; });
/* end of update policy */
+ if (!d_include_path.empty()) {
+ includePath(d_include_path);
+ }
}
void AuthLua4::postLoad() {
+#include "config.h"
#include <cassert>
#include <fstream>
#include <unordered_set>
#include <unordered_map>
#include <typeinfo>
+#include <sys/stat.h>
#include "logger.hh"
#include "logging.hh"
#include "iputils.hh"
#include "ext/luawrapper/include/LuaContext.hpp"
#include "dns_random.hh"
-BaseLua4::BaseLua4() = default;
-
-void BaseLua4::loadFile(const std::string& fname)
+void BaseLua4::loadFile(const std::string& fname, bool doPostLoad)
{
std::ifstream ifs(fname);
if (!ifs) {
auto ret = errno;
auto msg = stringerror(ret);
- SLOG(g_log << Logger::Error << "Unable to read configuration file from '" << fname << "': " << msg << endl,
- g_slog->withName("lua")->error(Logr::Error, ret, "Unable to read configuration file", "file", Logging::Loggable(fname), "msg", Logging::Loggable(msg)));
+ g_log << Logger::Error << "Unable to read configuration file from '" << fname << "': " << msg << endl;
throw std::runtime_error(msg);
}
- loadStream(ifs);
+ loadStream(ifs, doPostLoad);
};
void BaseLua4::loadString(const std::string &script) {
std::istringstream iss(script);
- loadStream(iss);
+ loadStream(iss, true);
+};
+
+void BaseLua4::includePath(const std::string& directory) {
+ std::vector<std::string> vec;
+ const std::string& suffix = "lua";
+ auto directoryError = pdns::visit_directory(directory, [this, &directory, &suffix, &vec]([[maybe_unused]] ino_t inodeNumber, const std::string_view& name) {
+ (void)this;
+ if (boost::starts_with(name, ".")) {
+ return true; // skip any dots
+ }
+ if (boost::ends_with(name, suffix)) {
+ // build name
+ string fullName = directory + "/" + std::string(name);
+ // ensure it's readable file
+ struct stat statInfo
+ {
+ };
+ if (stat(fullName.c_str(), &statInfo) != 0 || !S_ISREG(statInfo.st_mode)) {
+ string msg = fullName + " is not a regular file";
+ g_log << Logger::Error << msg << std::endl;
+ throw PDNSException(msg);
+ }
+ vec.emplace_back(fullName);
+ }
+ return true;
+ });
+
+ if (directoryError) {
+ int err = errno;
+ string msg = directory + " is not accessible: " + stringerror(err);
+ g_log << Logger::Error << msg << std::endl;
+ throw PDNSException(msg);
+ }
+
+ std::sort(vec.begin(), vec.end(), CIStringComparePOSIX());
+
+ for(const auto& file: vec) {
+ loadFile(file, false);
+ }
};
// By default no features
d_lw->writeVariable("pdns", d_pd);
}
-void BaseLua4::loadStream(std::istream &stream) {
+void BaseLua4::loadStream(std::istream &stream, bool doPostLoad) {
d_lw->executeCode(stream);
- postLoad();
+ if (doPostLoad) {
+ postLoad();
+ }
}
BaseLua4::~BaseLua4() = default;
{
protected:
std::unique_ptr<LuaContext> d_lw; // this is way on top because it must get destroyed _last_
+ std::string d_include_path; // path where scripts to include at postLoad are
public:
- BaseLua4();
- void loadFile(const std::string& fname);
- void loadString(const std::string& script);
- void loadStream(std::istream& stream);
+ BaseLua4(const std::string &includePath) : d_include_path(includePath) {};
+ void loadFile(const std::string &fname, bool doPostLoad=true);
+ void loadString(const std::string &script);
+ void loadStream(std::istream &stream, bool doPostLoad=true);
+ void includePath(const std::string &directory);
virtual ~BaseLua4(); // this is so unique_ptr works with an incomplete type
protected:
void prepareContext();