diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 5c32c72e0..ab5367465 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -74,7 +74,7 @@ struct plugins *plugins_new(const tal_t *ctx, struct log_book *log_book, p->log = new_log(p, log_book, NULL, "plugin-manager"); p->ld = ld; p->startup = true; - p->json_cmds = tal_arr(p, struct command *, 0); + p->plugin_cmds = tal_arr(p, struct plugin_command *, 0); p->blacklist = tal_arr(p, const char *, 0); p->shutdown = false; p->plugin_idx = 0; @@ -154,27 +154,27 @@ static void check_plugins_manifests(struct plugins *plugins) static void check_plugins_initted(struct plugins *plugins) { - struct command **json_cmds; + struct plugin_command **plugin_cmds; if (!plugins_all_in_state(plugins, INIT_COMPLETE)) return; /* Clear commands first, in case callbacks add new ones. * Paranoia, but wouldn't that be a nasty bug to find? */ - json_cmds = plugins->json_cmds; - plugins->json_cmds = tal_arr(plugins, struct command *, 0); - for (size_t i = 0; i < tal_count(json_cmds); i++) - plugin_cmd_all_complete(plugins, json_cmds[i]); - tal_free(json_cmds); + plugin_cmds = plugins->plugin_cmds; + plugins->plugin_cmds = tal_arr(plugins, struct plugin_command *, 0); + for (size_t i = 0; i < tal_count(plugin_cmds); i++) + plugin_cmd_all_complete(plugins, plugin_cmds[i]); + tal_free(plugin_cmds); } struct command_result *plugin_register_all_complete(struct lightningd *ld, - struct command *cmd) + struct plugin_command *pcmd) { if (plugins_all_in_state(ld->plugins, INIT_COMPLETE)) - return plugin_cmd_all_complete(ld->plugins, cmd); + return plugin_cmd_all_complete(ld->plugins, pcmd); - tal_arr_expand(&ld->plugins->json_cmds, cmd); + tal_arr_expand(&ld->plugins->plugin_cmds, pcmd); return NULL; } @@ -216,7 +216,7 @@ static void destroy_plugin(struct plugin *p) } struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES, - struct command *start_cmd, bool important, + struct plugin_command *start_cmd, bool important, const char *parambuf STEALS, const jsmntok_t *params STEALS) { diff --git a/lightningd/plugin.h b/lightningd/plugin.h index 9fae129cf..207ee3d42 100644 --- a/lightningd/plugin.h +++ b/lightningd/plugin.h @@ -51,8 +51,9 @@ struct plugin { struct io_conn *stdin_conn, *stdout_conn; struct plugins *plugins; const char **plugin_path; + /* If there's a json command which ordered this to start */ - struct command *start_cmd; + struct plugin_command *start_cmd; enum plugin_state plugin_state; @@ -122,7 +123,7 @@ struct plugins { const char *default_dir; /* If there are json commands waiting for plugin resolutions. */ - struct command **json_cmds; + struct plugin_command **plugin_cmds; /* Blacklist of plugins from --disable-plugin */ const char **blacklist; @@ -222,7 +223,7 @@ void plugins_free(struct plugins *plugins); */ struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES, - struct command *start_cmd, + struct plugin_command *start_cmd, bool important, const char *parambuf STEALS, const jsmntok_t *params STEALS); @@ -283,7 +284,7 @@ struct plugin *find_plugin_for_command(struct lightningd *ld, * plugin_cmd_all_complete(). */ struct command_result *plugin_register_all_complete(struct lightningd *ld, - struct command *cmd); + struct plugin_command *pcmd); /** * Send the configure message to all plugins. diff --git a/lightningd/plugin_control.c b/lightningd/plugin_control.c index f70ee7179..06aaf3f42 100644 --- a/lightningd/plugin_control.c +++ b/lightningd/plugin_control.c @@ -6,21 +6,22 @@ #include /* A dummy structure used to give multiple arguments to callbacks. */ -struct dynamic_plugin { - struct plugin *plugin; +struct plugin_command { struct command *cmd; + const char *subcmd; }; /** * Returned by all subcommands on success. */ -static struct command_result *plugin_dynamic_list_plugins(struct command *cmd, +static struct command_result *plugin_dynamic_list_plugins(struct plugin_command *pcmd, const struct plugins *plugins) { struct json_stream *response; const struct plugin *p; - response = json_stream_success(cmd); + response = json_stream_success(pcmd->cmd); + json_add_string(response, "command", pcmd->subcmd); json_array_start(response, "plugins"); list_for_each(&plugins->plugins, p, list) { json_object_start(response, NULL); @@ -30,25 +31,25 @@ static struct command_result *plugin_dynamic_list_plugins(struct command *cmd, json_object_end(response); } json_array_end(response); - return command_success(cmd, response); + return command_success(pcmd->cmd, response); } -struct command_result *plugin_cmd_killed(struct command *cmd, +struct command_result *plugin_cmd_killed(struct plugin_command *pcmd, struct plugin *plugin, const char *msg) { - return command_fail(cmd, PLUGIN_ERROR, "%s: %s", plugin->cmd, msg); + return command_fail(pcmd->cmd, PLUGIN_ERROR, "%s: %s", plugin->cmd, msg); } -struct command_result *plugin_cmd_succeeded(struct command *cmd, +struct command_result *plugin_cmd_succeeded(struct plugin_command *pcmd, struct plugin *plugin) { - return plugin_dynamic_list_plugins(cmd, plugin->plugins); + return plugin_dynamic_list_plugins(pcmd, plugin->plugins); } struct command_result *plugin_cmd_all_complete(struct plugins *plugins, - struct command *cmd) + struct plugin_command *pcmd) { - return plugin_dynamic_list_plugins(cmd, plugins); + return plugin_dynamic_list_plugins(pcmd, plugins); } /** @@ -56,25 +57,25 @@ struct command_result *plugin_cmd_all_complete(struct plugins *plugins, * will give a result 60 seconds later at the most (once init completes). */ static struct command_result * -plugin_dynamic_start(struct command *cmd, const char *plugin_path, +plugin_dynamic_start(struct plugin_command *pcmd, const char *plugin_path, const char *buffer, const jsmntok_t *params) { - struct plugin *p = plugin_register(cmd->ld->plugins, plugin_path, cmd, false, buffer, params); + struct plugin *p = plugin_register(pcmd->cmd->ld->plugins, plugin_path, pcmd, false, buffer, params); const char *err; if (!p) - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, + return command_fail(pcmd->cmd, JSONRPC2_INVALID_PARAMS, "%s: already registered", plugin_path); /* This will come back via plugin_cmd_killed or plugin_cmd_succeeded */ err = plugin_send_getmanifest(p); if (err) - return command_fail(cmd, PLUGIN_ERROR, + return command_fail(pcmd->cmd, PLUGIN_ERROR, "%s: %s", plugin_path, err); - return command_still_pending(cmd); + return command_still_pending(pcmd->cmd); } /** @@ -82,22 +83,22 @@ plugin_dynamic_start(struct command *cmd, const char *plugin_path, * all contained plugins recursively and then starts them. */ static struct command_result * -plugin_dynamic_startdir(struct command *cmd, const char *dir_path) +plugin_dynamic_startdir(struct plugin_command *pcmd, const char *dir_path) { const char *err; struct command_result *res; - err = add_plugin_dir(cmd->ld->plugins, dir_path, false); + err = add_plugin_dir(pcmd->cmd->ld->plugins, dir_path, false); if (err) - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "%s", err); + return command_fail(pcmd->cmd, JSONRPC2_INVALID_PARAMS, "%s", err); /* If none added, this calls plugin_cmd_all_complete immediately */ - res = plugin_register_all_complete(cmd->ld, cmd); + res = plugin_register_all_complete(pcmd->cmd->ld, pcmd); if (res) return res; - plugins_send_getmanifest(cmd->ld->plugins); - return command_still_pending(cmd); + plugins_send_getmanifest(pcmd->cmd->ld->plugins); + return command_still_pending(pcmd->cmd); } static struct command_result * @@ -116,6 +117,7 @@ plugin_dynamic_stop(struct command *cmd, const char *plugin_name) plugin_kill(p, LOG_INFORM, "stopped by lightningd via RPC"); response = json_stream_success(cmd); + json_add_string(response, "command", "stop"); json_add_string(response, "result", take(tal_fmt(NULL, "Successfully stopped %s.", plugin_name))); @@ -131,20 +133,20 @@ plugin_dynamic_stop(struct command *cmd, const char *plugin_name) * Look for additions in the default plugin directory. */ static struct command_result * -plugin_dynamic_rescan_plugins(struct command *cmd) +plugin_dynamic_rescan_plugins(struct plugin_command *pcmd) { struct command_result *res; /* This will not fail on "already registered" error. */ - plugins_add_default_dir(cmd->ld->plugins); + plugins_add_default_dir(pcmd->cmd->ld->plugins); /* If none added, this calls plugin_cmd_all_complete immediately */ - res = plugin_register_all_complete(cmd->ld, cmd); + res = plugin_register_all_complete(pcmd->cmd->ld, pcmd); if (res) return res; - plugins_send_getmanifest(cmd->ld->plugins); - return command_still_pending(cmd); + plugins_send_getmanifest(pcmd->cmd->ld->plugins); + return command_still_pending(pcmd->cmd); } /** @@ -156,6 +158,7 @@ static struct command_result *json_plugin_control(struct command *cmd, const jsmntok_t *obj UNNEEDED, const jsmntok_t *params) { + struct plugin_command *pcmd; const char *subcmd; subcmd = param_subcommand(cmd, buffer, params, "start", "stop", "startdir", @@ -163,6 +166,10 @@ static struct command_result *json_plugin_control(struct command *cmd, if (!subcmd) return command_param_failed(); + pcmd = tal(cmd, struct plugin_command); + pcmd->cmd = cmd; + pcmd->subcmd = subcmd; + if (streq(subcmd, "stop")) { const char *plugin_name; @@ -202,7 +209,7 @@ static struct command_result *json_plugin_control(struct command *cmd, "plugin") - 1, 1); } if (access(plugin_path, X_OK) == 0) - return plugin_dynamic_start(cmd, plugin_path, + return plugin_dynamic_start(pcmd, plugin_path, buffer, mod_params); else return command_fail(cmd, JSONRPC2_INVALID_PARAMS, @@ -218,7 +225,7 @@ static struct command_result *json_plugin_control(struct command *cmd, return command_param_failed(); if (access(dir_path, F_OK) == 0) - return plugin_dynamic_startdir(cmd, dir_path); + return plugin_dynamic_startdir(pcmd, dir_path); else return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Could not open %s", dir_path); @@ -228,14 +235,14 @@ static struct command_result *json_plugin_control(struct command *cmd, NULL)) return command_param_failed(); - return plugin_dynamic_rescan_plugins(cmd); + return plugin_dynamic_rescan_plugins(pcmd); } else if (streq(subcmd, "list")) { if (!param(cmd, buffer, params, p_req("subcommand", param_ignore, cmd), NULL)) return command_param_failed(); - return plugin_dynamic_list_plugins(cmd, cmd->ld->plugins); + return plugin_dynamic_list_plugins(pcmd, cmd->ld->plugins); } /* subcmd must be one of the above: param_subcommand checked it! */ diff --git a/lightningd/plugin_control.h b/lightningd/plugin_control.h index 8d1e6ffbf..655149081 100644 --- a/lightningd/plugin_control.h +++ b/lightningd/plugin_control.h @@ -3,16 +3,18 @@ #include "config.h" #include +struct plugin_command; + /* Plugin startup failed */ -struct command_result *plugin_cmd_killed(struct command *cmd, +struct command_result *plugin_cmd_killed(struct plugin_command *pcmd, struct plugin *plugin, const char *msg); /* Plugin startup succeeded */ -struct command_result *plugin_cmd_succeeded(struct command *cmd, +struct command_result *plugin_cmd_succeeded(struct plugin_command *pcmd, struct plugin *plugin); /* All plugins succeeded/failed */ struct command_result *plugin_cmd_all_complete(struct plugins *plugins, - struct command *cmd); + struct plugin_command *pcmd); #endif /* LIGHTNING_LIGHTNINGD_PLUGIN_CONTROL_H */