This file is where it all happens - main is here, as are the two pivotal threads qthread() and athread()
*/
-void daemonize(void)
+static void daemonize(void)
{
if(fork())
exit(0); // bye bye
string fname=::arg()["socket-dir"];
if (::arg()["socket-dir"].empty()) {
if (::arg()["chroot"].empty())
- fname = LOCALSTATEDIR;
+ fname = std::string(LOCALSTATEDIR) + "/pdns";
else
fname = ::arg()["chroot"] + "/";
} else if (!::arg()["socket-dir"].empty() && !::arg()["chroot"].empty()) {
if(of)
of<<getpid()<<endl;
else
- g_log<<Logger::Error<<"Writing pid for "<<getpid()<<" to "<<fname<<" failed: "<<strerror(errno)<<endl;
+ g_log<<Logger::Error<<"Writing pid for "<<getpid()<<" to "<<fname<<" failed: "<<stringerror()<<endl;
}
int g_fd1[2], g_fd2[2];
FILE *g_fp;
-pthread_mutex_t g_guardian_lock = PTHREAD_MUTEX_INITIALIZER;
+std::mutex g_guardian_lock;
// The next two methods are not in dynhandler.cc because they use a few items declared in this file.
static string DLCycleHandler(const vector<string>&parts, pid_t ppid)
}
line.append(1,'\n');
- Lock l(&g_guardian_lock);
+ std::lock_guard<std::mutex> l(g_guardian_lock);
try {
writen2(g_fd1[1],line.c_str(),line.size()+1);
bool first=true;
cpid=0;
- pthread_mutex_lock(&g_guardian_lock);
+ g_guardian_lock.lock();
for(;;) {
int pid;
setStatus("Launching child");
if(pipe(g_fd1)<0 || pipe(g_fd2)<0) {
- g_log<<Logger::Critical<<"Unable to open pipe for coprocess: "<<strerror(errno)<<endl;
+ g_log<<Logger::Critical<<"Unable to open pipe for coprocess: "<<stringerror()<<endl;
exit(1);
}
close(g_fd2[1]);
}
if(execvp(argv[0], newargv)<0) {
- g_log<<Logger::Error<<"Unable to execvp '"<<argv[0]<<"': "<<strerror(errno)<<endl;
+ g_log<<Logger::Error<<"Unable to execvp '"<<argv[0]<<"': "<<stringerror()<<endl;
char **p=newargv;
while(*p)
g_log<<Logger::Error<<*p++<<endl;
writePid();
}
- pthread_mutex_unlock(&g_guardian_lock);
+ g_guardian_lock.unlock();
int status;
cpid=pid;
for(;;) {
int ret=waitpid(pid,&status,WNOHANG);
if(ret<0) {
- g_log<<Logger::Error<<"In guardian loop, waitpid returned error: "<<strerror(errno)<<endl;
+ g_log<<Logger::Error<<"In guardian loop, waitpid returned error: "<<stringerror()<<endl;
g_log<<Logger::Error<<"Dying"<<endl;
exit(1);
}
}
}
- pthread_mutex_lock(&g_guardian_lock);
+ g_guardian_lock.lock();
close(g_fd1[1]);
fclose(g_fp);
g_fp=0;
g_log<<Logger::Error<<"No clue what happened! Respawning"<<endl;
}
else {
- g_log<<Logger::Error<<"Unable to fork: "<<strerror(errno)<<endl;
+ g_log<<Logger::Error<<"Unable to fork: "<<stringerror()<<endl;
exit(1);
}
}
}
-#ifdef __GLIBC__ && !defined(__UCLIBC__)
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
#include <execinfo.h>
static void tbhandler(int num)
{
s_programname="pdns";
s_starttime=time(0);
-#ifdef __GLIBC__ && !defined(__UCLIBC__)
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
signal(SIGSEGV,tbhandler);
signal(SIGFPE,tbhandler);
signal(SIGABRT,tbhandler);
string configname=::arg()["config-dir"]+"/"+s_programname+".conf";
cleanSlashes(configname);
- if(!::arg().mustDo("config") && !::arg().mustDo("no-config")) // "config" == print a configuration file
+ if(::arg()["config"] != "default" && !::arg().mustDo("no-config")) // "config" == print a configuration file
::arg().laxFile(configname.c_str());
::arg().laxParse(argc,argv); // reparse so the commandline still wins
// we really need to do work - either standalone or as an instance
-#ifdef __GLIBC__ && !defined(__UCLIBC__)
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
if(!::arg().mustDo("traceback-handler")) {
g_log<<Logger::Warning<<"Disabling traceback handler"<<endl;
signal(SIGSEGV,SIG_DFL);
BackendMakers().launch(::arg()["launch"]); // vrooooom!
if(!::arg().getCommands().empty()) {
- cerr<<"Fatal: non-option on the command line, perhaps a '--setting=123' statement missed the '='?"<<endl;
+ cerr<<"Fatal: non-option";
+ if (::arg().getCommands().size() > 1) {
+ cerr<<"s";
+ }
+ cerr<<" (";
+ bool first = true;
+ for (const auto& c : ::arg().getCommands()) {
+ if (!first) {
+ cerr<<", ";
+ }
+ first = false;
+ cerr<<c;
+ }
+ cerr<<") on the command line, perhaps a '--setting=123' statement missed the '='?"<<endl;
exit(99);
}
}
if(::arg().mustDo("config")) {
- cout<<::arg().configstring()<<endl;
+ string config = ::arg()["config"];
+ if (config == "default") {
+ cout<<::arg().configstring(false, true);
+ } else if (config == "diff") {
+ cout<<::arg().configstring(true, false);
+ } else if (config == "check") {
+ try {
+ if(!::arg().mustDo("no-config"))
+ ::arg().file(configname.c_str());
+ ::arg().parse(argc,argv);
+ exit(0);
+ }
+ catch(const ArgException &A) {
+ cerr<<"Fatal error: "<<A.reason<<endl;
+ exit(1);
+ }
+ } else {
+ cout<<::arg().configstring(true, true);
+ }
exit(0);
}
if(isGuarded(argv)) {
g_log<<Logger::Warning<<"This is a guarded instance of pdns"<<endl;
- dl=new DynListener; // listens on stdin
+ dl=make_unique<DynListener>(); // listens on stdin
}
else {
g_log<<Logger::Warning<<"This is a standalone pdns"<<endl;
if(::arg().mustDo("control-console"))
- dl=new DynListener();
+ dl=make_unique<DynListener>();
else
- dl=new DynListener(s_programname);
+ dl=std::unique_ptr<DynListener>(new DynListener(s_programname));
writePid();
}
DynListener::registerFunc("REMOTES", &DLRemotesHandler, "get top remotes");
DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", "<var> <value>");
DynListener::registerFunc("RETRIEVE",&DLNotifyRetrieveHandler, "retrieve slave domain", "<domain>");
- DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "retrieve the current configuration");
+ DynListener::registerFunc("CURRENT-CONFIG",&DLCurrentConfigHandler, "retrieve the current configuration", "[diff|default]");
DynListener::registerFunc("LIST-ZONES",&DLListZones, "show list of zones", "[master|slave|native]");
DynListener::registerFunc("TOKEN-LOGIN", &DLTokenLogin, "Login to a PKCS#11 token", "<module> <slot> <pin>");
if(gethostname(tmp, sizeof(tmp)-1) == 0) {
::arg().set("server-id")=tmp;
} else {
- g_log<<Logger::Warning<<"Unable to get the hostname, NSID and id.server values will be empty: "<<strerror(errno)<<endl;
+ g_log<<Logger::Warning<<"Unable to get the hostname, NSID and id.server values will be empty: "<<stringerror()<<endl;
}
}