/* * This file is part of the Monero P2Pool * Copyright (c) 2021 SChernykh * Copyright (c) 2021 hyc * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "common.h" #include "console_commands.h" #include "p2pool.h" #include "stratum_server.h" #include "p2p_server.h" #include "side_chain.h" #include static constexpr char log_category_prefix[] = "ConsoleCommands "; namespace p2pool { bool ConsoleCommands::stopped = false; ConsoleCommands::ConsoleCommands(p2pool* pool) : m_pool(pool) { m_worker = new std::thread(&ConsoleCommands::run, this); } ConsoleCommands::~ConsoleCommands() { stopped = true; #ifdef _WIN32 TerminateThread(reinterpret_cast(m_worker->native_handle()), 0); #else pthread_cancel(m_worker->native_handle()); #endif m_worker->join(); delete m_worker; LOGINFO(1, "stopped"); } typedef struct strconst { const char *str; size_t len; } strconst; #define STRCONST(x) {x, sizeof(x)-1} #define STRCNULL {NULL, 0} typedef int (cmdfunc)(p2pool *pool, const char *args); typedef struct cmd { strconst name; const char *arg; const char *descr; cmdfunc *func; } cmd; static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_exit; static cmd cmds[] = { { STRCONST("help"), "", "display list of commands", do_help }, { STRCONST("status"), "", "display p2pool status", do_status }, { STRCONST("loglevel"), "", "set log level", do_loglevel }, { STRCONST("addpeers"), "", "add peer", do_addpeers }, { STRCONST("droppeers"), "", "disconnect all peers", do_droppeers }, { STRCONST("exit"), "", "terminate p2pool", do_exit }, { STRCNULL, NULL, NULL, NULL } }; static int do_help(p2pool * /* m_pool */, const char * /* args */) { int i; LOGINFO(0, "List of commands"); for (i=0; cmds[i].name.len; i++) LOGINFO(0, cmds[i].name.str << " " << cmds[i].arg << "\t" << cmds[i].descr); return 0; } static int do_status(p2pool *m_pool, const char * /* args */) { m_pool->side_chain().print_status(); if (m_pool->stratum_server()) { m_pool->stratum_server()->print_status(); } if (m_pool->p2p_server()) { m_pool->p2p_server()->print_status(); } bkg_jobs_tracker.print_status(); return 0; } static int do_loglevel(p2pool * /* m_pool */, const char *args) { int level = atoi(args); level = std::min(std::max(level, 0), log::MAX_GLOBAL_LOG_LEVEL); log::GLOBAL_LOG_LEVEL = level; LOGINFO(0, "log level set to " << level); return 0; } static int do_addpeers(p2pool *m_pool, const char *args) { if (m_pool->p2p_server()) { m_pool->p2p_server()->connect_to_peers(args); } return 0; } static int do_droppeers(p2pool *m_pool, const char * /* args */) { if (m_pool->p2p_server()) { m_pool->p2p_server()->drop_connections(); } return 0; } static int do_exit(p2pool *m_pool, const char * /* args */) { bkg_jobs_tracker.wait(); m_pool->stop(); return 1; } void ConsoleCommands::run() { LOGINFO(1, "started"); std::string command; command.reserve(1024); do { std::getline(std::cin, command); if (std::cin.eof()) { LOGINFO(1, "EOF, stopping"); return; } if (stopped) { LOGINFO(1, "stopping"); return; } cmd* c = cmds; for (; c->name.len; ++c) { if (!strncmp(command.c_str(), c->name.str, c->name.len)) { const char *args = command.c_str() + c->name.len + 1; if (c->func(m_pool, args)) { LOGINFO(1, "exit requested, stopping"); return; } break; } } if (!c->name.len) { LOGWARN(0, "Unknown command " << command); } } while (true); } } // namespace p2pool