| 3229 | AUTODATA(json_command, &graceful_command); |
| 3230 | |
| 3231 | static struct command_result *json_disconnect(struct command *cmd, |
| 3232 | const char *buffer, |
| 3233 | const jsmntok_t *obj UNNEEDED, |
| 3234 | const jsmntok_t *params) |
| 3235 | { |
| 3236 | struct disconnect_command *dc; |
| 3237 | struct peer *peer; |
| 3238 | struct channel *channel; |
| 3239 | bool *force; |
| 3240 | |
| 3241 | if (!param_check(cmd, buffer, params, |
| 3242 | p_req("id", param_peer, &peer), |
| 3243 | p_opt_def("force", param_bool, &force, false), |
| 3244 | NULL)) |
| 3245 | return command_param_failed(); |
| 3246 | |
| 3247 | if (peer->connected == PEER_DISCONNECTED) { |
| 3248 | return command_fail(cmd, LIGHTNINGD, "Peer not connected"); |
| 3249 | } |
| 3250 | |
| 3251 | channel = peer_any_channel_bystate(peer, channel_state_wants_peercomms, |
| 3252 | NULL); |
| 3253 | if (channel && !*force) { |
| 3254 | return command_fail(cmd, LIGHTNINGD, |
| 3255 | "Peer has (at least one) channel in state %s", |
| 3256 | channel_state_name(channel)); |
| 3257 | } |
| 3258 | |
| 3259 | if (command_check_only(cmd)) |
| 3260 | return command_check_done(cmd); |
| 3261 | |
| 3262 | force_peer_disconnect(cmd->ld, peer, "disconnect command"); |
| 3263 | |
| 3264 | /* Connectd tells us when it's finally disconnected */ |
| 3265 | dc = tal(cmd, struct disconnect_command); |
| 3266 | dc->cmd = cmd; |
| 3267 | dc->id = peer->id; |
| 3268 | list_add_tail(&cmd->ld->disconnect_commands, &dc->list); |
| 3269 | tal_add_destructor(dc, destroy_disconnect_command); |
| 3270 | |
| 3271 | return command_still_pending(cmd); |
| 3272 | } |
| 3273 | |
| 3274 | static const struct json_command disconnect_command = { |
| 3275 | "disconnect", |
nothing calls this directly
no test coverage detected