| 478 | WARN_UNUSED_RESULT; |
| 479 | |
| 480 | static const char *plugin_notification_handle(struct plugin *plugin, |
| 481 | const jsmntok_t *toks) |
| 482 | { |
| 483 | const jsmntok_t *methtok, *paramstok; |
| 484 | const char *methname; |
| 485 | struct jsonrpc_notification *n; |
| 486 | methtok = json_get_member(plugin->buffer, toks, "method"); |
| 487 | paramstok = json_get_member(plugin->buffer, toks, "params"); |
| 488 | |
| 489 | if (!methtok || !paramstok) { |
| 490 | return tal_fmt(plugin, |
| 491 | "Malformed JSON-RPC notification missing " |
| 492 | "\"method\" or \"params\": %.*s", |
| 493 | toks->end - toks->start, |
| 494 | plugin->buffer + toks->start); |
| 495 | } |
| 496 | |
| 497 | /* Dispatch incoming notifications. This is currently limited |
| 498 | * to just a few method types, should this ever become |
| 499 | * unwieldy we can switch to the AUTODATA construction to |
| 500 | * register notification handlers in a variety of places. */ |
| 501 | if (json_tok_streq(plugin->buffer, methtok, "log")) { |
| 502 | return plugin_log_handle(plugin, paramstok); |
| 503 | } else if (json_tok_streq(plugin->buffer, methtok, "message") |
| 504 | || json_tok_streq(plugin->buffer, methtok, "progress")) { |
| 505 | return plugin_notify_handle(plugin, methtok, paramstok); |
| 506 | } |
| 507 | |
| 508 | methname = json_strdup(tmpctx, plugin->buffer, methtok); |
| 509 | |
| 510 | if (!plugin_notification_allowed(plugin, methname)) { |
| 511 | log_unusual(plugin->log, |
| 512 | "Plugin attempted to send a notification to topic " |
| 513 | "\"%s\" it hasn't declared in its manifest, not " |
| 514 | "forwarding to subscribers.", |
| 515 | methname); |
| 516 | } else if (notifications_have_topic(plugin->plugins, methname)) { |
| 517 | n = jsonrpc_notification_start(NULL, methname); |
| 518 | json_add_string(n->stream, "origin", plugin->shortname); |
| 519 | json_add_tok(n->stream, "payload", paramstok, plugin->buffer); |
| 520 | jsonrpc_notification_end(n); |
| 521 | |
| 522 | plugins_notify(plugin->plugins, take(n)); |
| 523 | } |
| 524 | return NULL; |
| 525 | } |
| 526 | |
| 527 | struct plugin_destroyed { |
| 528 | const struct plugin *plugin; |
no test coverage detected