}
}
-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)
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)
}
}
+
+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");
+}
+
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);
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];
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")));