diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dcc15c9c8e040a..b7f8d3fd5d52b7 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5176,127 +5176,129 @@ bool CWallet::BackupWallet(const std::string& strDest) // This should be called carefully: // either supply "wallet" (if already loaded) or "strWalletFile" (if wallet wasn't loaded yet) -bool AutoBackupWallet (CWallet* wallet, std::string strWalletFile, std::string& strBackupWarning, std::string& strBackupError) +bool AutoBackupWallet(CWallet* wallet, const std::string& strWalletFile_, std::string& strBackupWarningRet, std::string& strBackupErrorRet) { namespace fs = boost::filesystem; - strBackupWarning = strBackupError = ""; + strBackupWarningRet = strBackupErrorRet = ""; + std::string strWalletFile = ""; - if(nWalletBackups > 0) - { - fs::path backupsDir = GetBackupsDir(); + if (nWalletBackups <= 0) { + LogPrintf("Automatic wallet backups are disabled!\n"); + return false; + } - if (!fs::exists(backupsDir)) - { - // Always create backup folder to not confuse the operating system's file browser - LogPrintf("Creating backup folder %s\n", backupsDir.string()); - if(!fs::create_directories(backupsDir)) { - // smth is wrong, we shouldn't continue until it's resolved - strBackupError = strprintf(_("Wasn't able to create wallet backup folder %s!"), backupsDir.string()); - LogPrintf("%s\n", strBackupError); - nWalletBackups = -1; - return false; - } - } else if (!fs::is_directory(backupsDir)) { + fs::path backupsDir = GetBackupsDir(); + + if (!fs::exists(backupsDir)) + { + // Always create backup folder to not confuse the operating system's file browser + LogPrintf("Creating backup folder %s\n", backupsDir.string()); + if(!fs::create_directories(backupsDir)) { // smth is wrong, we shouldn't continue until it's resolved - strBackupError = strprintf(_("%s is not a valid backup folder!"), backupsDir.string()); - LogPrintf("%s\n", strBackupError); + strBackupErrorRet = strprintf(_("Wasn't able to create wallet backup folder %s!"), backupsDir.string()); + LogPrintf("%s\n", strBackupErrorRet); nWalletBackups = -1; return false; } + } else if (!fs::is_directory(backupsDir)) { + // smth is wrong, we shouldn't continue until it's resolved + strBackupErrorRet = strprintf(_("%s is not a valid backup folder!"), backupsDir.string()); + LogPrintf("%s\n", strBackupErrorRet); + nWalletBackups = -1; + return false; + } - // Create backup of the ... - std::string dateTimeStr = DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime()); - if (wallet) + // Create backup of the ... + std::string dateTimeStr = DateTimeStrFormat(".%Y-%m-%d-%H-%M", GetTime()); + if (wallet) + { + // ... opened wallet + LOCK2(cs_main, wallet->cs_wallet); + strWalletFile = wallet->strWalletFile; + fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr); + if(!wallet->BackupWallet(backupFile.string())) { + strBackupWarningRet = strprintf(_("Failed to create backup %s!"), backupFile.string()); + LogPrintf("%s\n", strBackupWarningRet); + nWalletBackups = -1; + return false; + } + // Update nKeysLeftSinceAutoBackup using current external keypool size + wallet->nKeysLeftSinceAutoBackup = wallet->KeypoolCountExternalKeys(); + LogPrintf("nKeysLeftSinceAutoBackup: %d\n", wallet->nKeysLeftSinceAutoBackup); + if(wallet->IsLocked(true)) { + strBackupWarningRet = _("Wallet is locked, can't replenish keypool! Automatic backups and mixing are disabled, please unlock your wallet to replenish keypool."); + LogPrintf("%s\n", strBackupWarningRet); + nWalletBackups = -2; + return false; + } + } else { + // ... strWalletFile file + strWalletFile = strWalletFile_; + fs::path sourceFile = GetDataDir() / strWalletFile; + fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr); + sourceFile.make_preferred(); + backupFile.make_preferred(); + if (fs::exists(backupFile)) { - // ... opened wallet - LOCK2(cs_main, wallet->cs_wallet); - strWalletFile = wallet->strWalletFile; - fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr); - if(!wallet->BackupWallet(backupFile.string())) { - strBackupWarning = strprintf(_("Failed to create backup %s!"), backupFile.string()); - LogPrintf("%s\n", strBackupWarning); + strBackupWarningRet = _("Failed to create backup, file already exists! This could happen if you restarted wallet in less than 60 seconds. You can continue if you are ok with this."); + LogPrintf("%s\n", strBackupWarningRet); + return false; + } + if(fs::exists(sourceFile)) { + try { + fs::copy_file(sourceFile, backupFile); + LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string()); + } catch(fs::filesystem_error &error) { + strBackupWarningRet = strprintf(_("Failed to create backup, error: %s"), error.what()); + LogPrintf("%s\n", strBackupWarningRet); nWalletBackups = -1; return false; } - // Update nKeysLeftSinceAutoBackup using current external keypool size - wallet->nKeysLeftSinceAutoBackup = wallet->KeypoolCountExternalKeys(); - LogPrintf("nKeysLeftSinceAutoBackup: %d\n", wallet->nKeysLeftSinceAutoBackup); - if(wallet->IsLocked(true)) { - strBackupWarning = _("Wallet is locked, can't replenish keypool! Automatic backups and mixing are disabled, please unlock your wallet to replenish keypool."); - LogPrintf("%s\n", strBackupWarning); - nWalletBackups = -2; - return false; - } - } else { - // ... strWalletFile file - fs::path sourceFile = GetDataDir() / strWalletFile; - fs::path backupFile = backupsDir / (strWalletFile + dateTimeStr); - sourceFile.make_preferred(); - backupFile.make_preferred(); - if (fs::exists(backupFile)) - { - strBackupWarning = _("Failed to create backup, file already exists! This could happen if you restarted wallet in less than 60 seconds. You can continue if you are ok with this."); - LogPrintf("%s\n", strBackupWarning); - return false; - } - if(fs::exists(sourceFile)) { - try { - fs::copy_file(sourceFile, backupFile); - LogPrintf("Creating backup of %s -> %s\n", sourceFile.string(), backupFile.string()); - } catch(fs::filesystem_error &error) { - strBackupWarning = strprintf(_("Failed to create backup, error: %s"), error.what()); - LogPrintf("%s\n", strBackupWarning); - nWalletBackups = -1; - return false; - } - } } + } - // Keep only the last 10 backups, including the new one of course - typedef std::multimap folder_set_t; - folder_set_t folder_set; - fs::directory_iterator end_iter; - backupsDir.make_preferred(); - // Build map of backup files for current(!) wallet sorted by last write time - fs::path currentFile; - for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) + // Keep only the last 10 backups, including the new one of course + typedef std::multimap folder_set_t; + folder_set_t folder_set; + fs::directory_iterator end_iter; + backupsDir.make_preferred(); + // Build map of backup files for current(!) wallet sorted by last write time + fs::path currentFile; + for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) + { + // Only check regular files + if ( fs::is_regular_file(dir_iter->status())) { - // Only check regular files - if ( fs::is_regular_file(dir_iter->status())) + currentFile = dir_iter->path().filename(); + // Only add the backups for the current wallet, e.g. wallet.dat.* + if(dir_iter->path().stem().string() == strWalletFile) { - currentFile = dir_iter->path().filename(); - // Only add the backups for the current wallet, e.g. wallet.dat.* - if(dir_iter->path().stem().string() == strWalletFile) - { - folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); - } + folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter)); } } + } - // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) - int counter = 0; - BOOST_REVERSE_FOREACH(PAIRTYPE(const std::time_t, fs::path) file, folder_set) + // Loop backward through backup files and keep the N newest ones (1 <= N <= 10) + int counter = 0; + BOOST_REVERSE_FOREACH(PAIRTYPE(const std::time_t, fs::path) file, folder_set) + { + counter++; + if (counter > nWalletBackups) { - counter++; - if (counter > nWalletBackups) - { - // More than nWalletBackups backups: delete oldest one(s) - try { - fs::remove(file.second); - LogPrintf("Old backup deleted: %s\n", file.second); - } catch(fs::filesystem_error &error) { - strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what()); - LogPrintf("%s\n", strBackupWarning); - return false; - } + // More than nWalletBackups backups: delete oldest one(s) + try { + fs::remove(file.second); + LogPrintf("Old backup deleted: %s\n", file.second); + } catch(fs::filesystem_error &error) { + strBackupWarningRet = strprintf(_("Failed to delete backup, error: %s"), error.what()); + LogPrintf("%s\n", strBackupWarningRet); + return false; } } - return true; } - LogPrintf("Automatic wallet backups are disabled!\n"); - return false; + return true; } CKeyPool::CKeyPool() { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index dcf62cafb6bc65..6bc21322a9de4f 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -78,7 +78,7 @@ extern const char * DEFAULT_WALLET_DAT; //! if set, all keys will be derived by using BIP39/BIP44 static const bool DEFAULT_USE_HD_WALLET = false; -bool AutoBackupWallet (CWallet* wallet, std::string strWalletFile, std::string& strBackupWarning, std::string& strBackupError); +bool AutoBackupWallet (CWallet* wallet, const std::string& strWalletFile_, std::string& strBackupWarningRet, std::string& strBackupErrorRet); class CBlockIndex; class CCoinControl;