From 0e44480705631ffe6a1f3086527411ecebfc0ec7 Mon Sep 17 00:00:00 2001
From: Nat Goodspeed <nat@lindenlab.com>
Date: Mon, 21 Dec 2009 14:24:21 -0500
Subject: [PATCH] Add event API to enumerate registered LLCommandHandler
 instances.

---
 indra/newview/llcommanddispatcherlistener.cpp | 13 +++++
 indra/newview/llcommanddispatcherlistener.h   |  1 +
 indra/newview/llcommandhandler.cpp            | 55 +++++++++++++++++++
 indra/newview/llcommandhandler.h              |  5 ++
 4 files changed, 74 insertions(+)

diff --git a/indra/newview/llcommanddispatcherlistener.cpp b/indra/newview/llcommanddispatcherlistener.cpp
index 00a20de30e..91baeaf989 100644
--- a/indra/newview/llcommanddispatcherlistener.cpp
+++ b/indra/newview/llcommanddispatcherlistener.cpp
@@ -31,6 +31,11 @@ LLCommandDispatcherListener::LLCommandDispatcherListener(/* LLCommandDispatcher*
         "[\"query\"] map of parameters, as if from ?key1=val&key2=val\n"
         "[\"trusted\"] boolean indicating trusted browser [default true]",
         &LLCommandDispatcherListener::dispatch);
+    add("enumerate",
+        "Post to [\"reply\"] a map of registered LLCommandHandler instances, containing\n"
+        "name key and (e.g.) untrusted flag",
+        &LLCommandDispatcherListener::enumerate,
+        LLSD().with("reply", LLSD()));
 }
 
 void LLCommandDispatcherListener::dispatch(const LLSD& params) const
@@ -45,3 +50,11 @@ void LLCommandDispatcherListener::dispatch(const LLSD& params) const
     LLCommandDispatcher::dispatch(params["cmd"], params["params"], params["query"], NULL,
                                   trusted_browser);
 }
+
+void LLCommandDispatcherListener::enumerate(const LLSD& params) const
+{
+    LLReqID reqID(params);
+    LLSD response(LLCommandDispatcher::enumerate());
+    reqID.stamp(response);
+    LLEventPumps::instance().obtain(params["reply"]).post(response);
+}
diff --git a/indra/newview/llcommanddispatcherlistener.h b/indra/newview/llcommanddispatcherlistener.h
index d0070ddd71..9bcddebcc1 100644
--- a/indra/newview/llcommanddispatcherlistener.h
+++ b/indra/newview/llcommanddispatcherlistener.h
@@ -23,6 +23,7 @@ public:
 
 private:
     void dispatch(const LLSD& params) const;
+    void enumerate(const LLSD& params) const;
 
     //LLCommandDispatcher* mDispatcher;
 };
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 8c7e7bea83..dc506a1692 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -36,6 +36,7 @@
 #include "llcommandhandler.h"
 #include "llnotificationsutil.h"
 #include "llcommanddispatcherlistener.h"
+#include "stringize.h"
 
 // system includes
 #include <boost/tokenizer.hpp>
@@ -67,6 +68,7 @@ public:
 				  bool trusted_browser);
 
 private:
+	friend LLSD LLCommandDispatcher::enumerate();
 	std::map<std::string, LLCommandHandlerInfo> mMap;
 };
 
@@ -175,3 +177,56 @@ bool LLCommandDispatcher::dispatch(const std::string& cmd,
 	return LLCommandHandlerRegistry::instance().dispatch(
 		cmd, params, query_map, web, trusted_browser);
 }
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value);
+
+LLSD LLCommandDispatcher::enumerate()
+{
+	LLSD response;
+	LLCommandHandlerRegistry& registry(LLCommandHandlerRegistry::instance());
+	for (std::map<std::string, LLCommandHandlerInfo>::const_iterator chi(registry.mMap.begin()),
+																	 chend(registry.mMap.end());
+		 chi != chend; ++chi)
+	{
+		LLSD info;
+		info["untrusted"] = chi->second.mUntrustedBrowserAccess;
+		info["untrusted_str"] = lookup(chi->second.mUntrustedBrowserAccess);
+		response[chi->first] = info;
+	}
+	return response;
+}
+
+/*------------------------------ lookup stuff ------------------------------*/
+struct symbol_info
+{
+	const char* name;
+	LLCommandHandler::EUntrustedAccess value;
+};
+
+#define ent(SYMBOL)										\
+	{													\
+		#SYMBOL + 28, /* skip "LLCommandHandler::UNTRUSTED_" prefix */	\
+		SYMBOL											\
+	}
+
+symbol_info symbols[] =
+{
+	ent(LLCommandHandler::UNTRUSTED_ALLOW),		  // allow commands from untrusted browsers
+	ent(LLCommandHandler::UNTRUSTED_BLOCK),		  // ignore commands from untrusted browsers
+	ent(LLCommandHandler::UNTRUSTED_THROTTLE)	  // allow untrusted, but only a few per min.
+};
+
+#undef ent
+
+static std::string lookup(LLCommandHandler::EUntrustedAccess value)
+{
+	for (symbol_info *sii(symbols), *siend(symbols + (sizeof(symbols)/sizeof(symbols[0])));
+		 sii != siend; ++sii)
+	{
+		if (sii->value == value)
+		{
+			return sii->name;
+		}
+	}
+	return STRINGIZE("UNTRUSTED_" << value);
+}
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 1bae6d9414..a1d4c880f5 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -34,6 +34,8 @@
 #ifndef LLCOMMANDHANDLER_H
 #define LLCOMMANDHANDLER_H
 
+#include "llsd.h"
+
 /* Example:  secondlife:///app/foo/<uuid>
    Command "foo" that takes one parameter, a UUID.
 
@@ -103,6 +105,9 @@ public:
 		// Execute a command registered via the above mechanism,
 		// passing string parameters.
 		// Returns true if command was found and executed correctly.
+	/// Return an LLSD::Map of registered LLCommandHandlers and associated
+	/// info (e.g. EUntrustedAccess).
+	static LLSD enumerate();
 };
 
 #endif
-- 
GitLab