Skip to content

Commit 20a70ad

Browse files
reklessrpc: duplicate json format of reckless listavailable output
1 parent f40e71e commit 20a70ad

1 file changed

Lines changed: 74 additions & 12 deletions

File tree

plugins/recklessrpc.c

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,51 @@ static struct io_plan *read_more(struct io_conn *conn, struct reckless *rkls)
6767
&rkls->stdout_new, read_more, rkls);
6868
}
6969

70+
static void dup_listavailable_result(struct reckless *reckless,
71+
struct json_stream *response,
72+
char *reckless_result,
73+
const jsmntok_t *results_tok)
74+
{
75+
json_array_start(response, "result");
76+
size_t plugins, requirements;
77+
const jsmntok_t *result, *requirement, *requirements_tok;
78+
const char *plugin_name, *short_description, *long_description, *entrypoint;
79+
80+
json_for_each_arr(plugins, result, results_tok) {
81+
json_object_start(response, NULL);
82+
83+
json_scan(tmpctx, reckless_result, result,
84+
"{name:%,"
85+
"short_description:%,"
86+
"long_description:%,"
87+
"entrypoint:%}",
88+
JSON_SCAN_TAL(tmpctx, json_strdup, &plugin_name),
89+
JSON_SCAN_TAL(tmpctx, json_strdup, &short_description),
90+
JSON_SCAN_TAL(tmpctx, json_strdup, &long_description),
91+
JSON_SCAN_TAL(tmpctx, json_strdup, &entrypoint));
92+
93+
json_add_string(response, "name", plugin_name);
94+
if (!streq(short_description, "null"))
95+
json_add_string(response, "short_description", short_description);
96+
if (!streq(long_description, "null"))
97+
json_add_string(response, "long_description", long_description);
98+
json_add_string(response, "entypoint", entrypoint);
99+
100+
json_array_start(response, "requirements");
101+
requirements_tok = json_get_member(reckless_result, result, "requirements");
102+
if (requirements_tok) {
103+
json_for_each_arr(requirements, requirement, requirements_tok) {
104+
json_add_string(response, NULL,
105+
json_strdup(tmpctx, reckless_result, requirement));
106+
}
107+
}
108+
json_array_end(response);
109+
110+
json_object_end(response);
111+
}
112+
json_array_end(response);
113+
}
114+
70115
static struct command_result *reckless_result(struct io_conn *conn,
71116
struct reckless *reckless)
72117
{
@@ -78,19 +123,30 @@ static struct command_result *reckless_result(struct io_conn *conn,
78123
reckless->process_failed);
79124
return command_finished(reckless->cmd, response);
80125
}
81-
const jsmntok_t *results, *result, *logs, *log, *conf;
126+
127+
/* The reckless utility outputs utf-8 and ends the transmission with
128+
* \u0004, which jsmn is unable to parse. */
129+
size_t out_length = strlen(reckless->stdoutbuf);
130+
char *trimmed;
131+
trimmed = reckless->stdoutbuf;
132+
if (reckless->stdoutbuf[out_length-1] <= 0x07) {
133+
plugin_log(plugin, LOG_DBG, "trimming \\u%04x from reckless output",reckless->stdoutbuf[out_length-1]);
134+
trimmed = tal_strndup(tmpctx, reckless->stdoutbuf, out_length - 1);
135+
}
136+
137+
const jsmntok_t *results, *result, *logs, *log, *conf, *next;
82138
size_t i;
83139
jsmn_parser parser;
84140
jsmntok_t *toks;
85141
toks = tal_arr(reckless, jsmntok_t, 5000);
86142
jsmn_init(&parser);
87143
int res;
88-
res = jsmn_parse(&parser, reckless->stdoutbuf,
89-
strlen(reckless->stdoutbuf), toks, tal_count(toks));
144+
res = jsmn_parse(&parser, trimmed,
145+
strlen(trimmed), toks, tal_count(toks));
90146
const char *err;
91147
if (res == JSMN_ERROR_INVAL)
92148
err = tal_fmt(tmpctx, "reckless returned invalid character in json "
93-
"output");
149+
"output. (total length %lu)", strlen(reckless->stdoutbuf));
94150
else if (res == JSMN_ERROR_PART)
95151
err = tal_fmt(tmpctx, "reckless returned partial output");
96152
else if (res == JSMN_ERROR_NOMEM )
@@ -100,39 +156,45 @@ static struct command_result *reckless_result(struct io_conn *conn,
100156
err = NULL;
101157

102158
if (err) {
103-
plugin_log(plugin, LOG_UNUSUAL, "failed to parse json: %s", err);
159+
if (res == JSMN_ERROR_INVAL)
160+
plugin_log(plugin, LOG_BROKEN, "invalid char in json");
104161
response = jsonrpc_stream_fail(reckless->cmd, PLUGIN_ERROR,
105162
err);
106163
return command_finished(reckless->cmd, response);
107164
}
108165

109166
response = jsonrpc_stream_success(reckless->cmd);
110-
results = json_get_member(reckless->stdoutbuf, toks, "result");
111-
conf = json_get_member(reckless->stdoutbuf, results, "requested_lightning_conf");
167+
results = json_get_member(trimmed, toks, "result");
168+
next = json_get_arr(results, 0);
169+
conf = json_get_member(trimmed, results, "requested_lightning_conf");
112170
if (conf) {
113-
plugin_log(plugin, LOG_DBG, "dealing with listconfigs output");
171+
plugin_log(plugin, LOG_DBG, "ingesting listconfigs output");
114172
json_object_start(response, "result");
115173
json_for_each_obj(i, result, results) {
116-
json_add_tok(response, json_strdup(tmpctx, reckless->stdoutbuf, result), result+1, reckless->stdoutbuf);
174+
json_add_tok(response, json_strdup(tmpctx, trimmed, result), result+1, trimmed);
117175
}
118176
json_object_end(response);
119177

178+
} else if (next && next->type == JSMN_OBJECT) {
179+
plugin_log(plugin, LOG_DBG, "ingesting listavailable output");
180+
dup_listavailable_result(reckless, response, trimmed, results);
181+
120182
} else {
121183
json_array_start(response, "result");
122184
json_for_each_arr(i, result, results) {
123185
json_add_string(response,
124186
NULL,
125-
json_strdup(reckless, reckless->stdoutbuf,
187+
json_strdup(reckless, trimmed,
126188
result));
127189
}
128190
json_array_end(response);
129191
}
130192
json_array_start(response, "log");
131-
logs = json_get_member(reckless->stdoutbuf, toks, "log");
193+
logs = json_get_member(trimmed, toks, "log");
132194
json_for_each_arr(i, log, logs) {
133195
json_add_string(response,
134196
NULL,
135-
json_strdup(reckless, reckless->stdoutbuf,
197+
json_strdup(reckless, trimmed,
136198
log));
137199
}
138200
json_array_end(response);

0 commit comments

Comments
 (0)