Monero
Loading...
Searching...
No Matches
console_handler.h
Go to the documentation of this file.
1// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without
5// modification, are permitted provided that the following conditions are met:
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above copyright
9// notice, this list of conditions and the following disclaimer in the
10// documentation and/or other materials provided with the distribution.
11// * Neither the name of the Andrey N. Sabelnikov nor the
12// names of its contributors may be used to endorse or promote products
13// derived from this software without specific prior written permission.
14//
15// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
19// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25//
26
27#pragma once
28
29#include "misc_log_ex.h"
30#include "string_tools.h"
31#include <atomic>
32#include <condition_variable>
33#include <functional>
34#include <mutex>
35#include <thread>
36#include <iostream>
37#ifdef __OpenBSD__
38#include <stdio.h>
39#endif
40#include <boost/thread.hpp>
41#include <boost/algorithm/string/classification.hpp>
42#include <boost/algorithm/string/split.hpp>
43
44#ifdef HAVE_READLINE
45 #include "readline_buffer.h"
46#endif
47
48#undef MONERO_DEFAULT_LOG_CATEGORY
49#define MONERO_DEFAULT_LOG_CATEGORY "console_handler"
50
51namespace epee
52{
54 {
55 public:
57 : m_run(true)
60 {
61#ifdef HAVE_READLINE
62 m_readline_buffer.start();
63#endif
64 m_reader_thread = boost::thread(std::bind(&async_stdin_reader::reader_thread_func, this));
65 }
66
68 {
69 try { stop(); }
70 catch (...) { /* ignore */ }
71 }
72
73#ifdef HAVE_READLINE
74 rdln::readline_buffer& get_readline_buffer()
75 {
76 return m_readline_buffer;
77 }
78#endif
79
80 // Not thread safe. Only one thread can call this method at once.
81 bool get_line(std::string& line)
82 {
83 if (!start_read())
84 return false;
85
87 return false;
88
89 boost::unique_lock<boost::mutex> lock(m_response_mutex);
90 while (state_init == m_read_status)
91 {
92 m_response_cv.wait(lock);
93 }
94
95 bool res = false;
97 {
98 line = m_line;
99 res = true;
100 }
101
102 if (!eos() && m_read_status != state_cancelled)
104
105 return res;
106 }
107
108 bool eos() const { return m_read_status == state_eos; }
109
110 void stop()
111 {
112 if (m_run)
113 {
114 m_run.store(false, std::memory_order_relaxed);
115
116#if defined(WIN32)
117 ::CloseHandle(::GetStdHandle(STD_INPUT_HANDLE));
118#endif
119
120 m_request_cv.notify_one();
121 m_reader_thread.join();
122#ifdef HAVE_READLINE
123 m_readline_buffer.stop();
124#endif
125 }
126 }
127
128 void cancel()
129 {
130 boost::unique_lock<boost::mutex> lock(m_response_mutex);
132 m_has_read_request = false;
133 m_response_cv.notify_one();
134 }
135
136 private:
138 {
139 boost::unique_lock<boost::mutex> lock(m_request_mutex);
140 if (!m_run.load(std::memory_order_relaxed) || m_has_read_request)
141 return false;
142
143 m_has_read_request = true;
144 m_request_cv.notify_one();
145 return true;
146 }
147
149 {
150 boost::unique_lock<boost::mutex> lock(m_request_mutex);
151 while (m_run.load(std::memory_order_relaxed) && !m_has_read_request)
152 {
153 m_request_cv.wait(lock);
154 }
155
157 {
158 m_has_read_request = false;
159 return true;
160 }
161
162 return false;
163 }
164
166 {
167#if !defined(WIN32)
168 #if defined(__OpenBSD__) || defined(__ANDROID__)
169 int stdin_fileno = fileno(stdin);
170 #else
171 int stdin_fileno = ::fileno(stdin);
172 #endif
173
174 while (m_run.load(std::memory_order_relaxed))
175 {
177 return false;
178
179 fd_set read_set;
180 FD_ZERO(&read_set);
181 FD_SET(stdin_fileno, &read_set);
182
183 struct timeval tv;
184 tv.tv_sec = 0;
185 tv.tv_usec = 100 * 1000;
186
187 int retval = ::select(stdin_fileno + 1, &read_set, NULL, NULL, &tv);
188 if (retval < 0)
189 return false;
190 else if (0 < retval)
191 return true;
192 }
193#else
194 while (m_run.load(std::memory_order_relaxed))
195 {
197 return false;
198
199 DWORD retval = ::WaitForSingleObject(::GetStdHandle(STD_INPUT_HANDLE), 100);
200 switch (retval)
201 {
202 case WAIT_FAILED:
203 return false;
204 case WAIT_OBJECT_0:
205 return true;
206 default:
207 break;
208 }
209 }
210#endif
211
212 return true;
213 }
214
216 {
217 while (true)
218 {
219 if (!wait_read())
220 break;
221
222 std::string line;
223 bool read_ok = true;
224#ifdef HAVE_READLINE
225reread:
226#endif
227 if (wait_stdin_data())
228 {
229 if (m_run.load(std::memory_order_relaxed))
230 {
231#ifdef HAVE_READLINE
232 switch (m_readline_buffer.get_line(line))
233 {
234 case rdln::empty: goto eof;
235 case rdln::partial: goto reread;
236 case rdln::full: break;
237 }
238#else
240 std::getline(std::cin, line);
241#endif
242 read_ok = !std::cin.eof() && !std::cin.fail();
243 }
244 }
245 else
246 {
247 read_ok = false;
248 }
249 if (std::cin.eof()) {
250#ifdef HAVE_READLINE
251eof:
252#endif
254 m_response_cv.notify_one();
255 break;
256 }
257 else
258 {
259 boost::unique_lock<boost::mutex> lock(m_response_mutex);
260 if (m_run.load(std::memory_order_relaxed))
261 {
262 m_line = std::move(line);
264 }
265 else
266 {
268 }
269 m_response_cv.notify_one();
270 }
271 }
272 }
273
282
283 private:
284 boost::thread m_reader_thread;
285 std::atomic<bool> m_run;
286#ifdef HAVE_READLINE
287 rdln::readline_buffer m_readline_buffer;
288#endif
289
290 std::string m_line;
293
294 boost::mutex m_request_mutex;
295 boost::mutex m_response_mutex;
296 boost::condition_variable m_request_cv;
297 boost::condition_variable m_response_cv;
298 };
299
300
301 template<class t_server>
302 bool empty_commands_handler(t_server* psrv, const std::string& command)
303 {
304 return true;
305 }
306
307
309 {
310 public:
314
315 template<class t_server, class chain_handler>
316 bool run(t_server* psrv, chain_handler ch_handler, std::function<std::string(void)> prompt, const std::string& usage = "")
317 {
318 return run(prompt, usage, [&](const std::string& cmd) { return ch_handler(psrv, cmd); }, [&] { psrv->send_stop_signal(); });
319 }
320
321 template<class chain_handler>
322 bool run(chain_handler ch_handler, std::function<std::string(void)> prompt, const std::string& usage = "", std::function<void(void)> exit_handler = NULL)
323 {
324 return run(prompt, usage, [&](const boost::optional<std::string>& cmd) { return ch_handler(cmd); }, exit_handler);
325 }
326
327 void stop()
328 {
329 m_running = false;
330 m_stdin_reader.stop();
331 }
332
333 void cancel()
334 {
335 m_cancel = true;
336 m_stdin_reader.cancel();
337 }
338
340 {
341 std::string prompt = m_prompt();
342 if (!prompt.empty())
343 {
344#ifdef HAVE_READLINE
345 std::string color_prompt = "\001\033[1;33m\002" + prompt;
346 if (' ' != prompt.back())
347 color_prompt += " ";
348 color_prompt += "\001\033[0m\002";
349 m_stdin_reader.get_readline_buffer().set_prompt(color_prompt);
350#else
351 epee::set_console_color(epee::console_color_yellow, true);
352 std::cout << prompt;
353 if (' ' != prompt.back())
354 std::cout << ' ';
356 std::cout.flush();
357#endif
358 }
359 }
360
361 private:
362 template<typename t_cmd_handler>
363 bool run(std::function<std::string(void)> prompt, const std::string& usage, const t_cmd_handler& cmd_handler, std::function<void(void)> exit_handler)
364 {
365 bool continue_handle = true;
366 m_prompt = prompt;
367 while(continue_handle)
368 {
369 try
370 {
371 if (!m_running)
372 {
373 break;
374 }
375 print_prompt();
376
377 std::string command;
378 bool get_line_ret = m_stdin_reader.get_line(command);
379 if (!m_running)
380 break;
381 if (m_stdin_reader.eos())
382 {
383 MGINFO("EOF on stdin, exiting");
384 std::cout << std::endl;
385 break;
386 }
387
388 if (m_cancel)
389 {
390 MDEBUG("Input cancelled");
391 cmd_handler(boost::none);
392 m_cancel = false;
393 continue;
394 }
395 if (!get_line_ret)
396 {
397 MERROR("Failed to read line.");
398 }
399
400 string_tools::trim(command);
401
402 LOG_PRINT_L2("Read command: " << command);
403 if(cmd_handler(command))
404 {
405 continue;
406 }
407 else if(0 == command.compare("exit") || 0 == command.compare("q"))
408 {
409 continue_handle = false;
410 }
411 else
412 {
413#ifdef HAVE_READLINE
414 rdln::suspend_readline pause_readline;
415#endif
416 std::cout << "unknown command: " << command << std::endl;
417 std::cout << usage;
418 }
419 }
420 catch (const std::exception &ex)
421 {
422 LOG_ERROR("Exception at [console_handler], what=" << ex.what());
423 }
424 }
425 if (exit_handler)
426 exit_handler();
427 return true;
428 }
429
430 private:
432 std::atomic<bool> m_running = {true};
433 std::atomic<bool> m_cancel = {false};
434 std::function<std::string(void)> m_prompt;
435 };
436
437
438 template<class t_server, class t_handler>
439 bool start_default_console(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
440 {
441 std::shared_ptr<async_console_handler> console_handler = std::make_shared<async_console_handler>();
442 boost::thread([=](){console_handler->run<t_server, t_handler>(ptsrv, handlr, prompt, usage);}).detach();
443 return true;
444 }
445
446 template<class t_server, class t_handler>
447 bool start_default_console(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
448 {
449 return start_default_console(ptsrv, handlr, [prompt](){ return prompt; }, usage);
450 }
451
452 template<class t_server>
453 bool start_default_console(t_server* ptsrv, const std::string& prompt, const std::string& usage = "")
454 {
456 }
457
458 template<class t_server, class t_handler>
459 bool no_srv_param_adapter(t_server* ptsrv, const std::string& cmd, t_handler handlr)
460 {
461 return handlr(cmd);
462 }
463
464 template<class t_server, class t_handler>
465 bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
466 {
467 async_console_handler console_handler;
468 return console_handler.run(ptsrv, std::bind<bool>(no_srv_param_adapter<t_server, t_handler>, std::placeholders::_1, std::placeholders::_2, handlr), prompt, usage);
469 }
470
471 template<class t_server, class t_handler>
472 bool run_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
473 {
474 return run_default_console_handler_no_srv_param(ptsrv, handlr, [prompt](){return prompt;},usage);
475 }
476
477 template<class t_server, class t_handler>
478 bool start_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, std::function<std::string(void)> prompt, const std::string& usage = "")
479 {
480 boost::thread( boost::bind(run_default_console_handler_no_srv_param<t_server, t_handler>, ptsrv, handlr, prompt, usage) );
481 return true;
482 }
483
484 template<class t_server, class t_handler>
485 bool start_default_console_handler_no_srv_param(t_server* ptsrv, t_handler handlr, const std::string& prompt, const std::string& usage = "")
486 {
487 return start_default_console_handler_no_srv_param(ptsrv, handlr, [prompt](){return prompt;}, usage);
488 }
489
490 /*template<class a>
491 bool f(int i, a l)
492 {
493 return true;
494 }*/
495 /*
496 template<class chain_handler>
497 bool default_console_handler2(chain_handler ch_handler, const std::string usage)
498 */
499
500
501 /*template<class t_handler>
502 bool start_default_console2(t_handler handlr, const std::string& usage = "")
503 {
504 //std::string usage_local = usage;
505 boost::thread( boost::bind(default_console_handler2<t_handler>, handlr, usage) );
506 //boost::function<bool ()> p__ = boost::bind(f<t_handler>, 1, handlr);
507 //boost::function<bool ()> p__ = boost::bind(default_console_handler2<t_handler>, handlr, usage);
508 //boost::thread tr(p__);
509 return true;
510 }*/
511
513 public:
514 typedef boost::function<bool (const std::vector<std::string> &)> callback;
515 typedef boost::function<bool (void)> empty_callback;
516 typedef std::map<std::string, std::pair<callback, std::pair<std::string, std::string>>> lookup;
517
519 m_unknown_command_handler([](const std::vector<std::string>&){return false;}),
520 m_empty_command_handler([](){return true;}),
521 m_cancel_handler([](){return true;})
522 {
523 }
524
525 std::string get_usage()
526 {
527 std::stringstream ss;
528
529 for(auto& x:m_command_handlers)
530 {
531 ss << x.second.second.first << ENDL;
532 }
533 return ss.str();
534 }
535
536 std::pair<std::string, std::string> get_documentation(const std::vector<std::string>& cmd)
537 {
538 if(cmd.empty())
539 return std::make_pair("", "");
540 auto it = m_command_handlers.find(cmd.front());
541 if(it == m_command_handlers.end())
542 return std::make_pair("", "");
543 return it->second.second;
544 }
545
546 std::vector<std::string> get_command_list(const std::vector<std::string>& keywords = std::vector<std::string>())
547 {
548 std::vector<std::string> list;
549 list.reserve(m_command_handlers.size());
550 for(auto const& x:m_command_handlers)
551 {
552 bool take = true;
553 for(auto const& y:keywords)
554 {
555 bool in_usage = x.second.second.first.find(y) != std::string::npos;
556 bool in_description = x.second.second.second.find(y) != std::string::npos;
557 if (!(in_usage || in_description))
558 {
559 take = false;
560 break;
561 }
562 }
563 if (take)
564 {
565 list.push_back(x.first);
566 }
567 }
568 return list;
569 }
570
571 void set_handler(const std::string& cmd, const callback& hndlr, const std::string& usage = "", const std::string& description = "")
572 {
573 lookup::mapped_type & vt = m_command_handlers[cmd];
574 vt.first = hndlr;
575 vt.second.first = description.empty() ? cmd : usage;
576 vt.second.second = description.empty() ? usage : description;
577#ifdef HAVE_READLINE
579#endif
580 }
581
583 {
585 }
586
588 {
590 }
591
593 {
594 m_cancel_handler = hndlr;
595 }
596
597 bool process_command_vec(const std::vector<std::string>& cmd)
598 {
599 if(!cmd.size() || (cmd.size() == 1 && !cmd[0].size()))
601 auto it = m_command_handlers.find(cmd.front());
602 if(it == m_command_handlers.end())
603 return m_unknown_command_handler(cmd);
604 std::vector<std::string> cmd_local(cmd.begin()+1, cmd.end());
605 return it->second.first(cmd_local);
606 }
607
608 bool process_command_str(const boost::optional<std::string>& cmd)
609 {
610 if (!cmd)
611 return m_cancel_handler();
612 std::vector<std::string> cmd_v;
613 boost::split(cmd_v,*cmd,boost::is_any_of(" "), boost::token_compress_on);
614 return process_command_vec(cmd_v);
615 }
616 private:
621 };
622
623 /************************************************************************/
624 /* */
625 /************************************************************************/
627 {
630 std::unique_ptr<boost::thread> m_console_thread;
632 public:
634 try
635 {
637 if (m_console_thread.get() != nullptr)
638 {
639 m_console_thread->join();
640 }
641 }
642 catch (const std::exception &e) { /* ignore */ }
643 }
644
645 bool start_handling(std::function<std::string(void)> prompt, const std::string& usage_string = "", std::function<void(void)> exit_handler = NULL)
646 {
647 m_console_thread.reset(new boost::thread(boost::bind(&console_handlers_binder::run_handling, this, prompt, usage_string, exit_handler)));
648 return true;
649 }
650 bool start_handling(const std::string &prompt, const std::string& usage_string = "", std::function<void(void)> exit_handler = NULL)
651 {
652 return start_handling([prompt](){ return prompt; }, usage_string, exit_handler);
653 }
654
656 {
657 m_console_handler.stop();
658 }
659
660 bool run_handling(std::function<std::string(void)> prompt, const std::string& usage_string, std::function<void(void)> exit_handler = NULL)
661 {
662 return m_console_handler.run(std::bind(&console_handlers_binder::process_command_str, this, std::placeholders::_1), prompt, usage_string, exit_handler);
663 }
664
666 {
667 m_console_handler.print_prompt();
668 }
669
671 {
672 m_console_handler.cancel();
673 }
674 };
675
677 //template<class t_server>
678 //class srv_console_handlers_binder: public command_handler
679 //{
680 // async_console_handler m_console_handler;
681 //public:
682 // bool start_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string = "")
683 // {
684 // boost::thread(boost::bind(&srv_console_handlers_binder<t_server>::run_handling, this, psrv, prompt, usage_string)).detach();
685 // return true;
686 // }
687
688 // bool run_handling(t_server* psrv, const std::string& prompt, const std::string& usage_string)
689 // {
690 // return m_console_handler.run(psrv, boost::bind(&srv_console_handlers_binder<t_server>::process_command_str, this, _1, _2), prompt, usage_string);
691 // }
692
693 // void stop_handling()
694 // {
695 // m_console_handler.stop();
696 // }
697 //private:
698 // bool process_command_str(t_server* /*psrv*/, const std::string& cmd)
699 // {
700 // return console_handlers_binder::process_command_str(cmd);
701 // }
702 //};
703}
Definition console_handler.h:309
std::function< std::string(void)> m_prompt
Definition console_handler.h:434
void stop()
Definition console_handler.h:327
std::atomic< bool > m_running
Definition console_handler.h:432
void cancel()
Definition console_handler.h:333
bool run(chain_handler ch_handler, std::function< std::string(void)> prompt, const std::string &usage="", std::function< void(void)> exit_handler=NULL)
Definition console_handler.h:322
bool run(t_server *psrv, chain_handler ch_handler, std::function< std::string(void)> prompt, const std::string &usage="")
Definition console_handler.h:316
std::atomic< bool > m_cancel
Definition console_handler.h:433
async_stdin_reader m_stdin_reader
Definition console_handler.h:431
async_console_handler()
Definition console_handler.h:311
void print_prompt()
Definition console_handler.h:339
bool run(std::function< std::string(void)> prompt, const std::string &usage, const t_cmd_handler &cmd_handler, std::function< void(void)> exit_handler)
Definition console_handler.h:363
Definition console_handler.h:54
async_stdin_reader()
Definition console_handler.h:56
boost::mutex m_response_mutex
Definition console_handler.h:295
bool eos() const
Definition console_handler.h:108
void cancel()
Definition console_handler.h:128
bool wait_stdin_data()
Definition console_handler.h:165
boost::condition_variable m_request_cv
Definition console_handler.h:296
bool start_read()
Definition console_handler.h:137
bool wait_read()
Definition console_handler.h:148
boost::condition_variable m_response_cv
Definition console_handler.h:297
bool get_line(std::string &line)
Definition console_handler.h:81
boost::thread m_reader_thread
Definition console_handler.h:284
std::string m_line
Definition console_handler.h:290
void stop()
Definition console_handler.h:110
std::atomic< bool > m_run
Definition console_handler.h:285
boost::mutex m_request_mutex
Definition console_handler.h:294
t_state
Definition console_handler.h:275
@ state_success
Definition console_handler.h:277
@ state_eos
Definition console_handler.h:280
@ state_cancelled
Definition console_handler.h:279
@ state_error
Definition console_handler.h:278
@ state_init
Definition console_handler.h:276
t_state m_read_status
Definition console_handler.h:292
void reader_thread_func()
Definition console_handler.h:215
~async_stdin_reader()
Definition console_handler.h:67
bool m_has_read_request
Definition console_handler.h:291
boost::function< bool(void)> empty_callback
Definition console_handler.h:515
empty_callback m_empty_command_handler
Definition console_handler.h:619
std::vector< std::string > get_command_list(const std::vector< std::string > &keywords=std::vector< std::string >())
Definition console_handler.h:546
std::string get_usage()
Definition console_handler.h:525
empty_callback m_cancel_handler
Definition console_handler.h:620
void set_unknown_command_handler(const callback &hndlr)
Definition console_handler.h:582
callback m_unknown_command_handler
Definition console_handler.h:618
std::map< std::string, std::pair< callback, std::pair< std::string, std::string > > > lookup
Definition console_handler.h:516
lookup m_command_handlers
Definition console_handler.h:617
std::pair< std::string, std::string > get_documentation(const std::vector< std::string > &cmd)
Definition console_handler.h:536
void set_empty_command_handler(const empty_callback &hndlr)
Definition console_handler.h:587
command_handler()
Definition console_handler.h:518
boost::function< bool(const std::vector< std::string > &)> callback
Definition console_handler.h:514
bool process_command_vec(const std::vector< std::string > &cmd)
Definition console_handler.h:597
void set_handler(const std::string &cmd, const callback &hndlr, const std::string &usage="", const std::string &description="")
Definition console_handler.h:571
void set_cancel_handler(const empty_callback &hndlr)
Definition console_handler.h:592
bool process_command_str(const boost::optional< std::string > &cmd)
Definition console_handler.h:608
Definition console_handler.h:627
void stop_handling()
Definition console_handler.h:655
std::unique_ptr< boost::thread > m_console_thread
Definition console_handler.h:630
bool run_handling(std::function< std::string(void)> prompt, const std::string &usage_string, std::function< void(void)> exit_handler=NULL)
Definition console_handler.h:660
void print_prompt()
Definition console_handler.h:665
async_console_handler m_console_handler
Definition console_handler.h:631
command_handler::lookup command_handlers_map
Definition console_handler.h:629
bool start_handling(const std::string &prompt, const std::string &usage_string="", std::function< void(void)> exit_handler=NULL)
Definition console_handler.h:650
command_handler::callback console_command_handler
Definition console_handler.h:628
bool start_handling(std::function< std::string(void)> prompt, const std::string &usage_string="", std::function< void(void)> exit_handler=NULL)
Definition console_handler.h:645
void cancel_input()
Definition console_handler.h:670
~console_handlers_binder()
Definition console_handler.h:633
Definition readline_buffer.h:11
static void add_completion(const std::string &command)
Definition readline_buffer.cpp:104
Definition readline_buffer.h:35
#define true
#define false
const char * res
Definition hmac_keccak.cpp:42
#define const
Definition ipfrdr.c:80
static void usage(char *prog)
Definition mdb_drop.c:30
std::string & trim(std::string &str)
Definition string_tools.h:75
TODO: (mj-xmr) This will be reduced in an another PR.
Definition byte_slice.h:40
void set_console_color(int color, bool bright)
Definition mlog.cpp:349
bool empty_commands_handler(t_server *psrv, const std::string &command)
Definition console_handler.h:302
bool run_default_console_handler_no_srv_param(t_server *ptsrv, t_handler handlr, std::function< std::string(void)> prompt, const std::string &usage="")
Definition console_handler.h:465
bool no_srv_param_adapter(t_server *ptsrv, const std::string &cmd, t_handler handlr)
Definition console_handler.h:459
bool start_default_console(t_server *ptsrv, t_handler handlr, std::function< std::string(void)> prompt, const std::string &usage="")
Definition console_handler.h:439
void reset_console_color()
Definition mlog.cpp:471
bool start_default_console_handler_no_srv_param(t_server *ptsrv, t_handler handlr, std::function< std::string(void)> prompt, const std::string &usage="")
Definition console_handler.h:478
@ partial
Definition readline_buffer.h:9
@ full
Definition readline_buffer.h:9
@ empty
Definition readline_buffer.h:9
Definition enums.h:68
static void select(ge_precomp *t, int pos, signed char b)
Definition crypto-ops.c:1610