Browse Source

plugin: Add plugin rpcmethods to the JSON-RPC interface

Signed-off-by: Christian Decker <@cdecker>
plugin-6
Christian Decker 6 years ago
committed by Rusty Russell
parent
commit
7de4c40b77
  1. 106
      lightningd/plugin.c

106
lightningd/plugin.c

@ -6,6 +6,7 @@
#include <ccan/opt/opt.h> #include <ccan/opt/opt.h>
#include <ccan/pipecmd/pipecmd.h> #include <ccan/pipecmd/pipecmd.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/memleak.h>
#include <errno.h> #include <errno.h>
#include <lightningd/json.h> #include <lightningd/json.h>
#include <signal.h> #include <signal.h>
@ -383,6 +384,107 @@ static bool plugin_opts_add(const struct plugin_request *req)
return true; return true;
} }
static void plugin_rpcmethod_destroy(struct json_command *cmd)
{
}
static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
// FIXME: We could avoid parsing the buffer again if we were
// to also pass in the method name.
cmd->usage = "[params]";
command_still_pending(cmd);
}
static bool plugin_rpcmethod_add(struct plugin *plugin, const char *buffer,
const jsmntok_t *meth)
{
const jsmntok_t *nametok, *desctok, *longdesctok;
struct json_command *cmd;
nametok = json_get_member(buffer, meth, "name");
desctok = json_get_member(buffer, meth, "description");
longdesctok = json_get_member(buffer, meth, "long_description");
if (!nametok || nametok->type != JSMN_STRING) {
plugin_kill(
plugin,
tal_fmt(plugin,
"rpcmethod does not have a string \"name\": %.*s",
meth->end - meth->start, buffer + meth->start));
return false;
}
if (!desctok || desctok->type != JSMN_STRING) {
plugin_kill(plugin, tal_fmt(plugin,
"rpcmethod does not have a string "
"\"description\": %.*s",
meth->end - meth->start,
buffer + meth->start));
return false;
}
if (longdesctok && longdesctok->type != JSMN_STRING) {
plugin_kill(
plugin,
tal_fmt(plugin,
"\"long_description\" is not a string: %.*s",
meth->end - meth->start, buffer + meth->start));
return false;
}
cmd = notleak(tal(plugin, struct json_command));
cmd->name = tal_strndup(cmd, buffer + nametok->start,
nametok->end - nametok->start);
cmd->description = tal_strndup(cmd, buffer + desctok->start,
desctok->end - desctok->start);
if (longdesctok)
cmd->verbose =
tal_strndup(cmd, buffer + longdesctok->start,
longdesctok->end - longdesctok->start);
else
cmd->verbose = cmd->description;
cmd->deprecated = false;
cmd->dispatch = plugin_rpcmethod_dispatch;
tal_add_destructor(cmd, plugin_rpcmethod_destroy);
if (!jsonrpc_command_add(plugin->plugins->rpc, cmd)) {
log_broken(plugin->log,
"Could not register method \"%s\", a method with "
"that name is already registered",
cmd->name);
return false;
}
return true;
}
static bool plugin_rpcmethods_add(const struct plugin_request *req)
{
const char *buffer = req->plugin->buffer;
const jsmntok_t *cur, *methods;
/* This is the parent for all elements in the "options" array */
int methpos;
methods =
json_get_member(req->plugin->buffer, req->resulttok, "rpcmethods");
if (!methods)
return false;
methpos = methods - req->toks;
if (methods->type != JSMN_ARRAY) {
plugin_kill(req->plugin, "\"result.rpcmethods\" is not an array");
return false;
}
for (cur = methods + 1; cur->parent == methpos; cur = json_next(cur))
if (!plugin_rpcmethod_add(req->plugin, buffer, cur))
return false;
return true;
}
/** /**
* Callback for the plugin_manifest request. * Callback for the plugin_manifest request.
*/ */
@ -400,8 +502,8 @@ static void plugin_manifest_cb(const struct plugin_request *req, struct plugin *
return; return;
} }
if (!plugin_opts_add(req)) if (!plugin_opts_add(req) || !plugin_rpcmethods_add(req))
return; plugin_kill(plugin, "Failed to register options or methods");
} }
void plugins_init(struct plugins *plugins) void plugins_init(struct plugins *plugins)

Loading…
Cancel
Save