]> granicus.if.org Git - pdns/commitdiff
make pdns_control help work, even in guardian setups!
authorPeter van Dijk <peter.van.dijk@netherlabs.nl>
Fri, 17 Feb 2012 09:02:18 +0000 (09:02 +0000)
committerPeter van Dijk <peter.van.dijk@netherlabs.nl>
Fri, 17 Feb 2012 09:02:18 +0000 (09:02 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@2410 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/dynlistener.cc
pdns/dynlistener.hh
pdns/receiver.cc

index c9d29e3934870201806a70f9a7c179277cbf61a4..d8402b411a7c15823676ccc9adff5533b08618f4 100644 (file)
@@ -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<string> 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<string> 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");
+}
+
index 218d07f686cfd83384323ade8dd83f2f420e9254..3dbea2fb7311abd4c66c115c5cf642e83d3260a2 100644 (file)
@@ -50,12 +50,14 @@ public:
   static void *theListenerHelper(void *p);
 
   typedef string g_funk_t(const vector<string> &parts, Utility::pid_t ppid); // guido!
-  typedef map<string,g_funk_t *> g_funkdb_t;
+  typedef struct { g_funk_t *func; string args; string usage; } g_funkwithusage_t;
+  typedef map<string,g_funkwithusage_t> 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);
index 8c029bd564a3424c494f60371bc9a484b60209db..159b62f0600236d2cf608a4ccc322c4cfc7d49ec 100644 (file)
@@ -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", "<statistic>");
+    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", "<domain> <host>");
+    DynListener::registerFunc("NOTIFY",&DLNotifyHandler, "queue a notification", "<domain>");
+    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", "[<record>]");
+    DynListener::registerFunc("CCOUNTS",&DLCCHandler, "get cache statistics");
+    DynListener::registerFunc("SET",&DLSettingsHandler, "set config variables", "<var> <value>");
+    DynListener::registerFunc("RETRIEVE",&DLNotifyRetrieveHandler, "retrieve slave domain", "<domain>");
 
     if(!::arg()["tcp-control-address"].empty()) {
       DynListener* dlTCP=new DynListener(ComboAddress(::arg()["tcp-control-address"], ::arg().asNum("tcp-control-port")));