From: Peter van Dijk Date: Fri, 17 Feb 2012 09:02:18 +0000 (+0000) Subject: make pdns_control help work, even in guardian setups! X-Git-Tag: auth-3.1-rc1~116 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3c90953ee475dba4516ccb04805ee6491a3ac894;p=pdns make pdns_control help work, even in guardian setups! git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2410 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dynlistener.cc b/pdns/dynlistener.cc index c9d29e393..d8402b411 100644 --- a/pdns/dynlistener.cc +++ b/pdns/dynlistener.cc @@ -271,9 +271,10 @@ void DynListener::sendLine(const string &l) } } -void DynListener::registerFunc(const string &name, g_funk_t *gf) +void DynListener::registerFunc(const string &name, g_funk_t *gf, const string &usage, const string &args) { - s_funcdb[name]=gf; + g_funkwithusage_t e = {gf, args, usage}; + s_funcdb[name]=e; } void DynListener::registerRestFunc(g_funk_t *gf) @@ -299,15 +300,17 @@ void DynListener::theListener() continue; } parts[0] = toUpper( parts[0] ); - if(!s_funcdb[parts[0]]) { - if(s_restfunc) + if(!s_funcdb.count(parts[0])) { + if(parts[0] == "HELP") + sendLine(getHelp()); + else if(s_restfunc) sendLine((*s_restfunc)(parts,d_ppid)); else sendLine("Unknown command: '"+parts[0]+"'"); continue; } - sendLine((*s_funcdb[parts[0]])(parts,d_ppid)); + sendLine((*(s_funcdb[parts[0]].func))(parts,d_ppid)); } } catch(AhuException &AE) @@ -328,3 +331,33 @@ void DynListener::theListener() } } + +string DynListener::getHelp() +{ + vector funcs; + string rest; + + // s_restfunc, when in guardian mode, is the function that + // can pass commands on to the guarded instance + // we just pass it HELP and merge it with our own list + if(s_restfunc) + { + vector parts; + parts.push_back("HELP"); + rest=((*s_restfunc)(parts,d_ppid)); + boost::split(funcs, rest, boost::is_any_of("\n")); + } + + const boost::format fmter("%|-32| %||"); + + for(g_funkdb_t::const_iterator i=s_funcdb.begin();i!=s_funcdb.end();++i) + { + funcs.push_back(str(boost::format(fmter) % (toLower(i->first)+" "+i->second.args) % i->second.usage)); + } + sort(funcs.begin(), funcs.end()); + + // hack: this removes the duplicate quit method + unique(funcs.begin(), funcs.end()); + return boost::join(funcs, "\n"); +} + diff --git a/pdns/dynlistener.hh b/pdns/dynlistener.hh index 218d07f68..3dbea2fb7 100644 --- a/pdns/dynlistener.hh +++ b/pdns/dynlistener.hh @@ -50,12 +50,14 @@ public: static void *theListenerHelper(void *p); typedef string g_funk_t(const vector &parts, Utility::pid_t ppid); // guido! - typedef map g_funkdb_t; + typedef struct { g_funk_t *func; string args; string usage; } g_funkwithusage_t; + typedef map g_funkdb_t; - static void registerFunc(const string &name, g_funk_t *gf); + static void registerFunc(const string &name, g_funk_t *gf, const string &usage="", const string &args=""); static void registerRestFunc(g_funk_t *gf); private: void sendLine(const string &line); + string getHelp(); string getLine(); void listenOnUnixDomain(const std::string& fname); diff --git a/pdns/receiver.cc b/pdns/receiver.cc index 8c029bd56..159b62f06 100644 --- a/pdns/receiver.cc +++ b/pdns/receiver.cc @@ -181,10 +181,10 @@ static int guardian(int argc, char **argv) int infd=0, outfd=1; DynListener dlg(s_programname); - dlg.registerFunc("QUIT",&DLQuitHandler); - dlg.registerFunc("CYCLE",&DLCycleHandler); - dlg.registerFunc("PING",&DLPingHandler); - dlg.registerFunc("STATUS",&DLStatusHandler); + dlg.registerFunc("QUIT",&DLQuitHandler, "quit daemon"); + dlg.registerFunc("CYCLE",&DLCycleHandler, "restart instance"); + dlg.registerFunc("PING",&DLPingHandler, "ping guardian"); + dlg.registerFunc("STATUS",&DLStatusHandler, "get instance status from guardian"); dlg.registerRestFunc(&DLRestHandler); dlg.go(); string progname=argv[0]; @@ -537,19 +537,19 @@ int main(int argc, char **argv) writePid(); } - DynListener::registerFunc("SHOW",&DLShowHandler); - DynListener::registerFunc("RPING",&DLPingHandler); - DynListener::registerFunc("QUIT",&DLRQuitHandler); - DynListener::registerFunc("UPTIME",&DLUptimeHandler); - DynListener::registerFunc("NOTIFY-HOST",&DLNotifyHostHandler); - DynListener::registerFunc("NOTIFY",&DLNotifyHandler); - DynListener::registerFunc("RELOAD",&DLReloadHandler); - DynListener::registerFunc("REDISCOVER",&DLRediscoverHandler); - DynListener::registerFunc("VERSION",&DLVersionHandler); - DynListener::registerFunc("PURGE",&DLPurgeHandler); - DynListener::registerFunc("CCOUNTS",&DLCCHandler); - DynListener::registerFunc("SET",&DLSettingsHandler); - DynListener::registerFunc("RETRIEVE",&DLNotifyRetrieveHandler); + DynListener::registerFunc("SHOW",&DLShowHandler, "show a specific statistic or * to get a list", ""); + DynListener::registerFunc("RPING",&DLPingHandler, "ping instance"); + DynListener::registerFunc("QUIT",&DLRQuitHandler, "quit daemon"); + DynListener::registerFunc("UPTIME",&DLUptimeHandler, "get instance uptime"); + DynListener::registerFunc("NOTIFY-HOST",&DLNotifyHostHandler, "notify host for specific domain", " "); + DynListener::registerFunc("NOTIFY",&DLNotifyHandler, "queue a notification", ""); + DynListener::registerFunc("RELOAD",&DLReloadHandler, "reload all zones"); + DynListener::registerFunc("REDISCOVER",&DLRediscoverHandler, "discover any new zones"); + DynListener::registerFunc("VERSION",&DLVersionHandler, "get instance version"); + DynListener::registerFunc("PURGE",&DLPurgeHandler, "purge entries from packet cache", "[]"); + DynListener::registerFunc("CCOUNTS",&DLCCHandler, "get cache statistics"); + DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", " "); + DynListener::registerFunc("RETRIEVE",&DLNotifyRetrieveHandler, "retrieve slave domain", ""); if(!::arg()["tcp-control-address"].empty()) { DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));