| 1727 | } |
| 1728 | |
| 1729 | void plugin_main(char *argv[], |
| 1730 | const char *(*init)(struct plugin *p, |
| 1731 | const char *buf, const jsmntok_t *), |
| 1732 | const enum plugin_restartability restartability, |
| 1733 | bool init_rpc, |
| 1734 | struct feature_set *features STEALS, |
| 1735 | const struct plugin_command *commands TAKES, |
| 1736 | size_t num_commands, |
| 1737 | const struct plugin_notification *notif_subs TAKES, |
| 1738 | size_t num_notif_subs, |
| 1739 | const struct plugin_hook *hook_subs TAKES, |
| 1740 | size_t num_hook_subs, |
| 1741 | const char **notif_topics TAKES, |
| 1742 | size_t num_notif_topics, |
| 1743 | ...) |
| 1744 | { |
| 1745 | struct plugin *plugin; |
| 1746 | va_list ap; |
| 1747 | |
| 1748 | setup_locale(); |
| 1749 | |
| 1750 | daemon_maybe_debug(argv); |
| 1751 | |
| 1752 | /* Note this already prints to stderr, which is enough for now */ |
| 1753 | daemon_setup(argv[0], NULL, NULL); |
| 1754 | |
| 1755 | va_start(ap, num_notif_topics); |
| 1756 | plugin = new_plugin(NULL, argv[0], |
| 1757 | init, restartability, init_rpc, features, commands, |
| 1758 | num_commands, notif_subs, num_notif_subs, hook_subs, |
| 1759 | num_hook_subs, notif_topics, num_notif_topics, ap); |
| 1760 | va_end(ap); |
| 1761 | setup_command_usage(plugin); |
| 1762 | |
| 1763 | timers_init(&plugin->timers, time_mono()); |
| 1764 | |
| 1765 | io_new_conn(plugin, STDIN_FILENO, stdin_conn_init, plugin); |
| 1766 | io_new_conn(plugin, STDOUT_FILENO, stdout_conn_init, plugin); |
| 1767 | |
| 1768 | for (;;) { |
| 1769 | struct timer *expired = NULL; |
| 1770 | |
| 1771 | clean_tmpctx(); |
| 1772 | |
| 1773 | /* Will only exit if a timer has expired. */ |
| 1774 | io_loop(&plugin->timers, &expired); |
| 1775 | call_plugin_timer(plugin, expired); |
| 1776 | } |
| 1777 | |
| 1778 | tal_free(plugin); |
| 1779 | } |
| 1780 | |
| 1781 | static struct listpeers_channel *json_to_listpeers_channel(const tal_t *ctx, |
| 1782 | const char *buffer, |