Merge pull request #4971

15904610 simplewallet: remove extra colon in a few calls to input_secure_line (stoffu)
247dab73 simplewallet: avoid conversion to string in input_secure_line (stoffu)
bf9ef7ad simplewallet: factor yesno hint into input_line (stoffu)
This commit is contained in:
Riccardo Spagni 2019-01-18 09:23:03 +02:00
commit 4fb9cfa017
No known key found for this signature in database
GPG Key ID: 55432DF31CCD4FCD
1 changed files with 49 additions and 46 deletions

View File

@ -231,12 +231,15 @@ namespace
const char* USAGE_VERSION("version"); const char* USAGE_VERSION("version");
const char* USAGE_HELP("help [<command>]"); const char* USAGE_HELP("help [<command>]");
std::string input_line(const std::string& prompt) std::string input_line(const std::string& prompt, bool yesno = false)
{ {
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
rdln::suspend_readline pause_readline; rdln::suspend_readline pause_readline;
#endif #endif
std::cout << prompt; std::cout << prompt;
if (yesno)
std::cout << " (Y/Yes/N/No)";
std::cout << ": " << std::flush;
std::string buf; std::string buf;
#ifdef _WIN32 #ifdef _WIN32
@ -248,12 +251,12 @@ namespace
return epee::string_tools::trim(buf); return epee::string_tools::trim(buf);
} }
epee::wipeable_string input_secure_line(const std::string& prompt) epee::wipeable_string input_secure_line(const char *prompt)
{ {
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
rdln::suspend_readline pause_readline; rdln::suspend_readline pause_readline;
#endif #endif
auto pwd_container = tools::password_container::prompt(false, prompt.c_str(), false); auto pwd_container = tools::password_container::prompt(false, prompt, false);
if (!pwd_container) if (!pwd_container)
{ {
MERROR("Failed to read secure line"); MERROR("Failed to read secure line");
@ -426,10 +429,10 @@ namespace
<< ", " << dnssec_str << std::endl << ", " << dnssec_str << std::endl
<< sw::tr(" Monero Address = ") << addresses[0] << sw::tr(" Monero Address = ") << addresses[0]
<< std::endl << std::endl
<< sw::tr("Is this OK? (Y/n) ") << sw::tr("Is this OK?")
; ;
// prompt the user for confirmation given the dns query and dnssec status // prompt the user for confirmation given the dns query and dnssec status
std::string confirm_dns_ok = input_line(prompt.str()); std::string confirm_dns_ok = input_line(prompt.str(), true);
if (std::cin.eof()) if (std::cin.eof())
{ {
return {}; return {};
@ -597,7 +600,7 @@ namespace
fail_msg_writer() << boost::format(sw::tr("File %s likely stores wallet private keys! Use a different file name.")) % filename; fail_msg_writer() << boost::format(sw::tr("File %s likely stores wallet private keys! Use a different file name.")) % filename;
return false; return false;
} }
return command_line::is_yes(input_line((boost::format(sw::tr("File %s already exists. Are you sure to overwrite it? (Y/Yes/N/No): ")) % filename).str())); return command_line::is_yes(input_line((boost::format(sw::tr("File %s already exists. Are you sure to overwrite it?")) % filename).str(), true));
} }
return true; return true;
} }
@ -3154,9 +3157,9 @@ bool simple_wallet::ask_wallet_create_if_needed()
LOG_PRINT_L3("User asked to specify wallet file name."); LOG_PRINT_L3("User asked to specify wallet file name.");
wallet_path = input_line( wallet_path = input_line(
tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n" tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n"
"Wallet file name (or Ctrl-C to quit): " : "Wallet file name (or Ctrl-C to quit)" :
"Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n" "Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n"
"Wallet file name (or Ctrl-C to quit): ") "Wallet file name (or Ctrl-C to quit)")
); );
if(std::cin.eof()) if(std::cin.eof())
{ {
@ -3203,7 +3206,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
if (!m_restoring) if (!m_restoring)
{ {
message_writer() << tr("No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path; message_writer() << tr("No wallet found with that name. Confirm creation of new wallet named: ") << wallet_path;
confirm_creation = input_line(tr("(Y/Yes/N/No): ")); confirm_creation = input_line("", true);
if(std::cin.eof()) if(std::cin.eof())
{ {
LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()");
@ -3412,7 +3415,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{ {
m_wallet_file = m_generate_from_view_key; m_wallet_file = m_generate_from_view_key;
// parse address // parse address
std::string address_string = input_line("Standard address: "); std::string address_string = input_line("Standard address");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (address_string.empty()) { if (address_string.empty()) {
@ -3432,7 +3435,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
} }
// parse view secret key // parse view secret key
epee::wipeable_string viewkey_string = input_secure_line("Secret view key: "); epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (viewkey_string.empty()) { if (viewkey_string.empty()) {
@ -3467,7 +3470,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{ {
m_wallet_file = m_generate_from_spend_key; m_wallet_file = m_generate_from_spend_key;
// parse spend secret key // parse spend secret key
epee::wipeable_string spendkey_string = input_secure_line("Secret spend key: "); epee::wipeable_string spendkey_string = input_secure_line("Secret spend key");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (spendkey_string.empty()) { if (spendkey_string.empty()) {
@ -3487,7 +3490,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{ {
m_wallet_file = m_generate_from_keys; m_wallet_file = m_generate_from_keys;
// parse address // parse address
std::string address_string = input_line("Standard address: "); std::string address_string = input_line("Standard address");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (address_string.empty()) { if (address_string.empty()) {
@ -3507,7 +3510,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
} }
// parse spend secret key // parse spend secret key
epee::wipeable_string spendkey_string = input_secure_line("Secret spend key: "); epee::wipeable_string spendkey_string = input_secure_line("Secret spend key");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (spendkey_string.empty()) { if (spendkey_string.empty()) {
@ -3522,7 +3525,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
} }
// parse view secret key // parse view secret key
epee::wipeable_string viewkey_string = input_secure_line("Secret view key: "); epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (viewkey_string.empty()) { if (viewkey_string.empty()) {
@ -3569,7 +3572,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
unsigned int multisig_n; unsigned int multisig_n;
// parse multisig type // parse multisig type
std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1): "); std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1)");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (multisig_type_string.empty()) if (multisig_type_string.empty())
@ -3595,7 +3598,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n; message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n;
// parse multisig address // parse multisig address
std::string address_string = input_line("Multisig wallet address: "); std::string address_string = input_line("Multisig wallet address");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (address_string.empty()) { if (address_string.empty()) {
@ -3610,7 +3613,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
} }
// parse secret view key // parse secret view key
epee::wipeable_string viewkey_string = input_secure_line("Secret view key: "); epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (viewkey_string.empty()) if (viewkey_string.empty())
@ -3649,7 +3652,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
// get N secret spend keys from user // get N secret spend keys from user
for(unsigned int i=0; i<multisig_n; ++i) for(unsigned int i=0; i<multisig_n; ++i)
{ {
spendkey_string = input_secure_line(tr((boost::format(tr("Secret spend key (%u of %u):")) % (i+1) % multisig_m).str().c_str())); spendkey_string = input_secure_line(tr((boost::format(tr("Secret spend key (%u of %u)")) % (i+1) % multisig_m).str().c_str()));
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (spendkey_string.empty()) if (spendkey_string.empty())
@ -3726,7 +3729,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
wrt << tr("Assumed you are creating a new account, restore will be done from current estimated blockchain height."); wrt << tr("Assumed you are creating a new account, restore will be done from current estimated blockchain height.");
wrt << tr("Use --restore-height or --restore-date if you want to restore an already setup account from a specific height"); wrt << tr("Use --restore-height or --restore-date if you want to restore an already setup account from a specific height");
} }
std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): ")); std::string confirm = input_line(tr("Is this okay?"), true);
if (std::cin.eof() || !command_line::is_yes(confirm)) if (std::cin.eof() || !command_line::is_yes(confirm))
CHECK_AND_ASSERT_MES(false, false, tr("account creation aborted")); CHECK_AND_ASSERT_MES(false, false, tr("account creation aborted"));
@ -3782,9 +3785,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
{ {
std::string heightstr; std::string heightstr;
if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6)) if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6))
heightstr = input_line("Restore from specific blockchain height (optional, default 0): "); heightstr = input_line("Restore from specific blockchain height (optional, default 0)");
else else
heightstr = input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD): "); heightstr = input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD)");
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (heightstr.empty()) if (heightstr.empty())
@ -3813,7 +3816,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false; return false;
m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day); m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day);
success_msg_writer() << tr("Restore height is: ") << m_restore_height; success_msg_writer() << tr("Restore height is: ") << m_restore_height;
std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): ")); std::string confirm = input_line(tr("Is this okay?"), true);
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if(command_line::is_yes(confirm)) if(command_line::is_yes(confirm))
@ -3836,7 +3839,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
if (m_restore_height >= estimate_height) if (m_restore_height >= estimate_height)
{ {
success_msg_writer() << tr("Restore height ") << m_restore_height << (" is not yet reached. The current estimated height is ") << estimate_height; success_msg_writer() << tr("Restore height ") << m_restore_height << (" is not yet reached. The current estimated height is ") << estimate_height;
std::string confirm = input_line(tr("Still apply restore height? (Y/Yes/N/No): ")); std::string confirm = input_line(tr("Still apply restore height?"), true);
if (std::cin.eof() || command_line::is_no(confirm)) if (std::cin.eof() || command_line::is_no(confirm))
m_restore_height = 0; m_restore_height = 0;
} }
@ -3968,7 +3971,7 @@ std::string simple_wallet::get_mnemonic_language()
} }
while (language_number < 0) while (language_number < 0)
{ {
language_choice = input_line(tr("Enter the number corresponding to the language of your choice: ")); language_choice = input_line(tr("Enter the number corresponding to the language of your choice"));
if (std::cin.eof()) if (std::cin.eof())
return std::string(); return std::string();
try try
@ -5446,7 +5449,7 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
// prompt is there is no payment id and confirmation is required // prompt is there is no payment id and confirmation is required
if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && dsts.size() > num_subaddresses) if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && dsts.size() > num_subaddresses)
{ {
std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay?"), true);
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -5510,23 +5513,23 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
std::vector<std::pair<uint64_t, uint64_t>> nblocks = m_wallet->estimate_backlog({std::make_pair(worst_fee_per_byte, worst_fee_per_byte)}); std::vector<std::pair<uint64_t, uint64_t>> nblocks = m_wallet->estimate_backlog({std::make_pair(worst_fee_per_byte, worst_fee_per_byte)});
if (nblocks.size() != 1) if (nblocks.size() != 1)
{ {
prompt << "Internal error checking for backlog. " << tr("Is this okay anyway? (Y/Yes/N/No): "); prompt << "Internal error checking for backlog. " << tr("Is this okay anyway?");
} }
else else
{ {
if (nblocks[0].first > m_wallet->get_confirm_backlog_threshold()) if (nblocks[0].first > m_wallet->get_confirm_backlog_threshold())
prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay? (Y/Yes/N/No): ")) % nblocks[0].first).str(); prompt << (boost::format(tr("There is currently a %u block backlog at that fee level. Is this okay?")) % nblocks[0].first).str();
} }
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {
prompt << tr("Failed to check for backlog: ") << e.what() << ENDL << tr("Is this okay anyway? (Y/Yes/N/No): "); prompt << tr("Failed to check for backlog: ") << e.what() << ENDL << tr("Is this okay anyway?");
} }
std::string prompt_str = prompt.str(); std::string prompt_str = prompt.str();
if (!prompt_str.empty()) if (!prompt_str.empty())
{ {
std::string accepted = input_line(prompt_str); std::string accepted = input_line(prompt_str, true);
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -5612,9 +5615,9 @@ bool simple_wallet::transfer_main(int transfer_type, const std::vector<std::stri
{ {
prompt << tr("WARNING: this is a non default ring size, which may harm your privacy. Default is recommended."); prompt << tr("WARNING: this is a non default ring size, which may harm your privacy. Default is recommended.");
} }
prompt << ENDL << tr("Is this okay? (Y/Yes/N/No): "); prompt << ENDL << tr("Is this okay?");
std::string accepted = input_line(prompt.str()); std::string accepted = input_line(prompt.str(), true);
if (std::cin.eof()) if (std::cin.eof())
return false; return false;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -5752,17 +5755,17 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
std::string prompt_str = tr("Sweeping ") + print_money(total_unmixable); std::string prompt_str = tr("Sweeping ") + print_money(total_unmixable);
if (ptx_vector.size() > 1) { if (ptx_vector.size() > 1) {
prompt_str = (boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % prompt_str = (boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
print_money(total_unmixable) % print_money(total_unmixable) %
((unsigned long long)ptx_vector.size()) % ((unsigned long long)ptx_vector.size()) %
print_money(total_fee)).str(); print_money(total_fee)).str();
} }
else { else {
prompt_str = (boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % prompt_str = (boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
print_money(total_unmixable) % print_money(total_unmixable) %
print_money(total_fee)).str(); print_money(total_fee)).str();
} }
std::string accepted = input_line(prompt_str); std::string accepted = input_line(prompt_str, true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -5805,7 +5808,7 @@ bool simple_wallet::sweep_unmixable(const std::vector<std::string> &args_)
catch (const tools::error::not_enough_unlocked_money& e) catch (const tools::error::not_enough_unlocked_money& e)
{ {
fail_msg_writer() << tr("Not enough money in unlocked balance"); fail_msg_writer() << tr("Not enough money in unlocked balance");
std::string accepted = input_line((boost::format(tr("Discarding %s of unmixable outputs that cannot be spent, which can be undone by \"rescan_spent\". Is this okay? (Y/Yes/N/No): ")) % print_money(e.available())).str()); std::string accepted = input_line((boost::format(tr("Discarding %s of unmixable outputs that cannot be spent, which can be undone by \"rescan_spent\". Is this okay?")) % print_money(e.available())).str(), true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (command_line::is_yes(accepted)) if (command_line::is_yes(accepted))
@ -6013,7 +6016,7 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
// prompt is there is no payment id and confirmation is required // prompt is there is no payment id and confirmation is required
if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && !info.is_subaddress) if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && !info.is_subaddress)
{ {
std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay?"), true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -6061,17 +6064,17 @@ bool simple_wallet::sweep_main(uint64_t below, bool locked, const std::vector<st
if (m_wallet->print_ring_members() && !print_ring_members(ptx_vector, prompt)) if (m_wallet->print_ring_members() && !print_ring_members(ptx_vector, prompt))
return true; return true;
if (ptx_vector.size() > 1) { if (ptx_vector.size() > 1) {
prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % prompt << boost::format(tr("Sweeping %s in %llu transactions for a total fee of %s. Is this okay?")) %
print_money(total_sent) % print_money(total_sent) %
((unsigned long long)ptx_vector.size()) % ((unsigned long long)ptx_vector.size()) %
print_money(total_fee); print_money(total_fee);
} }
else { else {
prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
print_money(total_sent) % print_money(total_sent) %
print_money(total_fee); print_money(total_fee);
} }
std::string accepted = input_line(prompt.str()); std::string accepted = input_line(prompt.str(), true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -6281,7 +6284,7 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
// prompt if there is no payment id and confirmation is required // prompt if there is no payment id and confirmation is required
if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && !info.is_subaddress) if (!payment_id_seen && m_wallet->confirm_missing_payment_id() && !info.is_subaddress)
{ {
std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): ")); std::string accepted = input_line(tr("No payment id is included with this transaction. Is this okay?"), true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -6323,10 +6326,10 @@ bool simple_wallet::sweep_single(const std::vector<std::string> &args_)
std::ostringstream prompt; std::ostringstream prompt;
if (!print_ring_members(ptx_vector, prompt)) if (!print_ring_members(ptx_vector, prompt))
return true; return true;
prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay? (Y/Yes/N/No): ")) % prompt << boost::format(tr("Sweeping %s for a total fee of %s. Is this okay?")) %
print_money(total_sent) % print_money(total_sent) %
print_money(total_fee); print_money(total_fee);
std::string accepted = input_line(prompt.str()); std::string accepted = input_line(prompt.str(), true);
if (std::cin.eof()) if (std::cin.eof())
return true; return true;
if (!command_line::is_yes(accepted)) if (!command_line::is_yes(accepted))
@ -6590,8 +6593,8 @@ bool simple_wallet::accept_loaded_tx(const std::function<size_t()> get_num_txes,
change_string += tr("no change"); change_string += tr("no change");
uint64_t fee = amount - amount_to_dests; uint64_t fee = amount - amount_to_dests;
std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay? (Y/Yes/N/No): ")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % payment_id_string % extra_message).str(); std::string prompt_str = (boost::format(tr("Loaded %lu transactions, for %s, fee %s, %s, %s, with min ring size %lu, %s. %sIs this okay?")) % (unsigned long)get_num_txes() % print_money(amount) % print_money(fee) % dest_string % change_string % (unsigned long)min_ring_size % payment_id_string % extra_message).str();
return command_line::is_yes(input_line(prompt_str)); return command_line::is_yes(input_line(prompt_str, true));
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs) bool simple_wallet::accept_loaded_tx(const tools::wallet2::unsigned_tx_set &txs)
@ -7749,7 +7752,7 @@ bool simple_wallet::rescan_blockchain(const std::vector<std::string> &args_)
{ {
message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain."); message_writer() << tr("Warning: this will lose any information which can not be recovered from the blockchain.");
message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc"); message_writer() << tr("This includes destination addresses, tx secret keys, tx notes, etc");
std::string confirm = input_line(tr("Rescan anyway ? (Y/Yes/N/No): ")); std::string confirm = input_line(tr("Rescan anyway?"), true);
if(!std::cin.eof()) if(!std::cin.eof())
{ {
if (!command_line::is_yes(confirm)) if (!command_line::is_yes(confirm))