static void json_rhash(struct command *cmd, const char *buffer, const jsmntok_t *params) { struct json_result *response = new_json_result(cmd); jsmntok_t *secrettok; struct sha256 secret; if (!json_get_params(buffer, params, "secret", &secrettok, NULL)) { command_fail(cmd, "Need secret"); return; } if (!hex_decode(buffer + secrettok->start, secrettok->end - secrettok->start, &secret, sizeof(secret))) { command_fail(cmd, "'%.*s' is not a valid 32-byte hex value", (int)(secrettok->end - secrettok->start), buffer + secrettok->start); return; } /* Hash in place. */ sha256(&secret, &secret, sizeof(secret)); json_object_start(response, NULL); json_add_hex(response, "rhash", &secret, sizeof(secret)); json_object_end(response); command_success(cmd, response); }
static void json_stop(struct command *cmd, const char *buffer, const jsmntok_t *params) { struct json_result *response = new_json_result(cmd); /* This can't have closed yet! */ cmd->jcon->stop = true; json_add_string(response, NULL, "Shutting down"); command_success(cmd, response); }
static void json_echo(struct command *cmd, const char *buffer, const jsmntok_t *params) { struct json_result *response = new_json_result(cmd); json_object_start(response, NULL); json_add_num(response, "num", params->size); json_add_literal(response, "echo", json_tok_contents(buffer, params), json_tok_len(params)); json_object_end(response); command_success(cmd, response); }
static void json_help(struct command *cmd, const char *buffer, const jsmntok_t *params) { unsigned int i; struct json_result *response = new_json_result(cmd); json_array_start(response, NULL); for (i = 0; i < ARRAY_SIZE(cmdlist); i++) { json_add_object(response, "command", JSMN_STRING, cmdlist[i]->name, "description", JSMN_STRING, cmdlist[i]->description, NULL); } json_array_end(response); command_success(cmd, response); }
static void json_restart(struct command *cmd, const char *buffer, const jsmntok_t *params) { const jsmntok_t *p, *end; size_t n = 0; if (params->type != JSMN_ARRAY) { command_fail(cmd, "Need array to reexec"); return; } end = json_next(params); cmd->dstate->reexec = tal_arrz(cmd->dstate, char *, n+1); for (p = params + 1; p != end; p = json_next(p)) { tal_resizez(&cmd->dstate->reexec, n+2); cmd->dstate->reexec[n++] = tal_strndup(cmd->dstate->reexec, buffer + p->start, p->end - p->start); } debug_dump_peers(cmd->dstate); io_break(cmd->dstate); command_success(cmd, null_response(cmd)); }
static void json_getlog(struct command *cmd, const char *buffer, const jsmntok_t *params) { struct log_info info; struct log_record *lr = cmd->dstate->log_record; jsmntok_t *level; json_get_params(buffer, params, "?level", &level, NULL); info.num_skipped = 0; if (!level) info.level = LOG_INFORM; else if (json_tok_streq(buffer, level, "io")) info.level = LOG_IO; else if (json_tok_streq(buffer, level, "debug")) info.level = LOG_DBG; else if (json_tok_streq(buffer, level, "info")) info.level = LOG_INFORM; else if (json_tok_streq(buffer, level, "unusual")) info.level = LOG_UNUSUAL; else { command_fail(cmd, "Invalid level param"); return; } info.response = new_json_result(cmd); json_object_start(info.response, NULL); json_add_time(info.response, "creation_time", log_init_time(lr)->ts); json_add_num(info.response, "bytes_used", (unsigned int)log_used(lr)); json_add_num(info.response, "bytes_max", (unsigned int)log_max_mem(lr)); json_object_start(info.response, "log"); log_each_line(lr, log_to_json, &info); json_object_end(info.response); json_object_end(info.response); command_success(cmd, info.response); }
enum command_return client_process_line(struct client *client, char *line) { enum command_return ret; if (strcmp(line, "noidle") == 0) { if (client->idle_waiting) { /* send empty idle response and leave idle mode */ client->idle_waiting = false; command_success(client); client_write_output(client); } /* do nothing if the client wasn't idling: the client has already received the full idle response from client_idle_notify(), which he can now evaluate */ return COMMAND_RETURN_OK; } else if (client->idle_waiting) { /* during idle mode, clients must not send anything except "noidle" */ g_warning("[%u] command \"%s\" during idle", client->num, line); return COMMAND_RETURN_CLOSE; } if (client->cmd_list_OK >= 0) { if (strcmp(line, CLIENT_LIST_MODE_END) == 0) { g_debug("[%u] process command list", client->num); /* for scalability reasons, we have prepended each new command; now we have to reverse it to restore the correct order */ client->cmd_list = g_slist_reverse(client->cmd_list); ret = client_process_command_list(client, client->cmd_list_OK, client->cmd_list); g_debug("[%u] process command " "list returned %i", client->num, ret); if (ret == COMMAND_RETURN_CLOSE || client_is_expired(client)) return COMMAND_RETURN_CLOSE; if (ret == COMMAND_RETURN_OK) command_success(client); client_write_output(client); free_cmd_list(client->cmd_list); client->cmd_list = NULL; client->cmd_list_OK = -1; } else { size_t len = strlen(line) + 1; client->cmd_list_size += len; if (client->cmd_list_size > client_max_command_list_size) { g_warning("[%u] command list size (%lu) " "is larger than the max (%lu)", client->num, (unsigned long)client->cmd_list_size, (unsigned long)client_max_command_list_size); return COMMAND_RETURN_CLOSE; } new_cmd_list_ptr(client, line); ret = COMMAND_RETURN_OK; } } else { if (strcmp(line, CLIENT_LIST_MODE_BEGIN) == 0) { client->cmd_list_OK = 0; ret = COMMAND_RETURN_OK; } else if (strcmp(line, CLIENT_LIST_OK_MODE_BEGIN) == 0) { client->cmd_list_OK = 1; ret = COMMAND_RETURN_OK; } else { g_debug("[%u] process command \"%s\"", client->num, line); ret = command_process(client, 0, line); g_debug("[%u] command returned %i", client->num, ret); if (ret == COMMAND_RETURN_CLOSE || client_is_expired(client)) return COMMAND_RETURN_CLOSE; if (ret == COMMAND_RETURN_OK) command_success(client); client_write_output(client); } } return ret; }