int PNGPlugin_init(void) { if (NULL == handle) { handle = dlopen("exteplayer3png.so", RTLD_LAZY); if (handle) { char *error = NULL; dlerror(); /* Clear any existing error */ *(void **) (&SaveRGBAImage_handle) = dlsym(handle, "SaveRGBAImage"); if ((error = dlerror()) != NULL) { dlclose(handle); plugin_err("%s\n", error); return -2; } return 0; } plugin_err( "%s\n", dlerror()); } return -1; }
static struct command_result *waitsendpay_error(struct command *cmd, const char *buf, const jsmntok_t *error, struct pay_command *pc) { const jsmntok_t *codetok, *scidtok, *dirtok; int code; attempt_failed_tok(pc, "waitsendpay", buf, error); codetok = json_get_member(buf, error, "code"); if (!json_to_int(buf, codetok, &code)) plugin_err("waitsendpay error gave no 'code'? '%.*s'", error->end - error->start, buf + error->start); /* FIXME: Handle PAY_UNPARSEABLE_ONION! */ /* Many error codes are final. */ if (code != PAY_TRY_OTHER_ROUTE) { return forward_error(cmd, buf, error, pc); } scidtok = json_delve(buf, error, ".data.erring_channel"); if (!scidtok) plugin_err("waitsendpay error no erring_channel '%.*s'", error->end - error->start, buf + error->start); dirtok = json_delve(buf, error, ".data.erring_direction"); if (!dirtok) plugin_err("waitsendpay error no erring_direction '%.*s'", error->end - error->start, buf + error->start); if (time_after(time_now(), pc->stoptime)) { return waitsendpay_expired(cmd, pc); } /* If failure is in routehint part, try next one */ if (channel_in_routehint(pc->current_routehint, buf, scidtok)) return next_routehint(cmd, pc); /* Otherwise, add erring channel to exclusion list. */ tal_arr_expand(&pc->excludes, tal_fmt(pc->excludes, "%.*s/%c", scidtok->end - scidtok->start, buf + scidtok->start, buf[dirtok->start])); /* Try again. */ return start_pay_attempt(cmd, pc, "Excluded channel %s", pc->excludes[tal_count(pc->excludes)-1]); }
/* Is this (erring) channel within the routehint itself? */ static bool channel_in_routehint(const struct route_info *routehint, const char *buf, const jsmntok_t *scidtok) { struct short_channel_id scid; if (!json_to_short_channel_id(buf, scidtok, &scid, false)) plugin_err("bad erring_channel '%.*s'", scidtok->end - scidtok->start, buf + scidtok->start); for (size_t i = 0; i < tal_count(routehint); i++) if (short_channel_id_eq(&scid, &routehint[i].short_channel_id)) return true; return false; }