| 247 | } |
| 248 | |
| 249 | struct plugin *plugin_register(struct plugins *plugins, const char* path TAKES, |
| 250 | struct plugin_command *start_cmd, bool important, |
| 251 | const char *parambuf STEALS, |
| 252 | const jsmntok_t *params STEALS) |
| 253 | { |
| 254 | struct plugin *p, *p_temp; |
| 255 | char* abspath; |
| 256 | u32 chksum; |
| 257 | |
| 258 | abspath = path_canon(tmpctx, path); |
| 259 | if (!abspath) { |
| 260 | return NULL; |
| 261 | } |
| 262 | /* Don't register an already registered plugin */ |
| 263 | list_for_each(&plugins->plugins, p_temp, list) { |
| 264 | if (streq(abspath, p_temp->cmd)) { |
| 265 | /* If added as "important", upgrade to "important". */ |
| 266 | if (important) |
| 267 | p_temp->important = true; |
| 268 | /* stop and restart plugin on different checksum */ |
| 269 | chksum = file_checksum(plugins->ld, path); |
| 270 | if (p_temp->checksum != chksum && !p_temp->important) { |
| 271 | plugin_kill(p_temp, LOG_INFORM, |
| 272 | "Plugin changed, needs restart."); |
| 273 | break; |
| 274 | } |
| 275 | if (taken(path)) |
| 276 | tal_free(path); |
| 277 | return NULL; |
| 278 | } |
| 279 | } |
| 280 | |
| 281 | p = tal(plugins, struct plugin); |
| 282 | p->plugins = plugins; |
| 283 | p->cmd = tal_steal(p, abspath); |
| 284 | p->checksum = file_checksum(plugins->ld, p->cmd); |
| 285 | p->shortname = path_basename(p, p->cmd); |
| 286 | p->start_cmd = start_cmd; |
| 287 | |
| 288 | p->plugin_state = UNCONFIGURED; |
| 289 | p->js_arr = tal_arr(p, struct json_stream *, 0); |
| 290 | p->used = 0; |
| 291 | p->notification_topics = tal_arr(p, const char *, 0); |
| 292 | p->subscriptions = NULL; |
| 293 | p->dynamic = false; |
| 294 | p->index = plugins->plugin_idx++; |
| 295 | |
| 296 | p->log = new_log(p, plugins->log_book, NULL, "plugin-%s", p->shortname); |
| 297 | p->methods = tal_arr(p, const char *, 0); |
| 298 | list_head_init(&p->plugin_opts); |
| 299 | |
| 300 | list_add_tail(&plugins->plugins, &p->list); |
| 301 | tal_add_destructor(p, destroy_plugin); |
| 302 | list_head_init(&p->pending_rpccalls); |
| 303 | |
| 304 | p->important = important; |
| 305 | p->parambuf = tal_steal(p, parambuf); |
| 306 | p->params = tal_steal(p, params); |
no test coverage detected