#include "ini.hpp" #include "crypto.hpp" #include "storage.hpp" #include "nntp_server.hpp" #include "event.hpp" #include "exec_frontend.hpp" #include #include int main(int argc, char * argv[]) { if (argc != 2) { std::cerr << "usage: " << argv[0] << " config.ini" << std::endl; return 1; } nntpchan::Crypto crypto(); nntpchan::Mainloop loop; nntpchan::NNTPServer nntp(loop); std::string fname(argv[1]); std::ifstream i(fname); if(i.is_open()) { INI::Parser conf(i); std::vector requiredSections = {"nntp", "articles"}; auto & level = conf.top(); for ( const auto & section : requiredSections ) { if(level.sections.find(section) == level.sections.end()) { std::cerr << "config file " << fname << " does not have required section: "; std::cerr << section << std::endl; return 1; } } auto & storeconf = level.sections["articles"].values; if (storeconf.find("store_path") == storeconf.end()) { std::cerr << "storage section does not have 'store_path' value" << std::endl; return 1; } nntp.SetStoragePath(storeconf["store_path"]); auto & nntpconf = level.sections["nntp"].values; if (nntpconf.find("bind") == nntpconf.end()) { std::cerr << "nntp section does not have 'bind' value" << std::endl; return 1; } if(nntpconf.find("instance_name") == nntpconf.end()) { std::cerr << "nntp section lacks 'instance_name' value" << std::endl; return 1; } nntp.SetInstanceName(nntpconf["instance_name"]); if (nntpconf.find("authdb") != nntpconf.end()) { nntp.SetLoginDB(nntpconf["authdb"]); } if ( level.sections.find("frontend") != level.sections.end()) { // frontend enabled auto & frontconf = level.sections["frontend"].values; if (frontconf.find("type") == frontconf.end()) { std::cerr << "frontend section provided but 'type' value not provided" << std::endl; return 1; } auto ftype = frontconf["type"]; if (ftype == "exec") { if (frontconf.find("exec") == frontconf.end()) { std::cerr << "exec frontend specified but no 'exec' value provided" << std::endl; return 1; } nntp.SetFrontend(new nntpchan::ExecFrontend(frontconf["exec"])); } else { std::cerr << "unknown frontend type '" << ftype << "'" << std::endl; return 1; } } auto & a = nntpconf["bind"]; try { nntp.Bind(a); } catch ( std::exception & ex ) { std::cerr << "failed to bind: " << ex.what() << std::endl; return 1; } std::cerr << "nntpd for " << nntp.InstanceName() << " bound to " << a << std::endl; loop.Run(); } else { std::cerr << "failed to open " << fname << std::endl; return 1; } }