std::filesystem

Converts all use of boost::filesystem to std::filesystem.

For macos and potentially other exotic systems where std::filesystem
isn't available, we use ghc::filesystem instead (which is a drop-in
replacement for std::filesystem, unlike boost::filesystem).

This also greatly changes how we handle filenames internally by holding
them in filesystem::path objects as soon as possible (using
fs::u8path()), rather than strings, which avoids a ton of issues around
unicode filenames.  As a result this lets us drop the boost::locale
dependency on Windows along with a bunch of messy Windows ifdef code,
and avoids the need for doing gross boost locale codecvt calls.
This commit is contained in:
Jason Rhinelander 2020-10-22 14:55:33 -03:00
parent f3e9c1a693
commit 1dd98f3dae
143 changed files with 1193 additions and 1768 deletions

3
.gitmodules vendored
View File

@ -25,3 +25,6 @@
[submodule "external/cpr"]
path = external/cpr
url = https://github.com/whoshuu/cpr.git
[submodule "external/ghc-filesystem"]
path = external/ghc-filesystem
url = https://github.com/gulrak/filesystem.git

View File

@ -33,11 +33,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(INSERT CMAKE_MODULE_PATH 0
"${CMAKE_SOURCE_DIR}/cmake")
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckLinkerFlag)
include(CheckLibraryExists)
include(CheckFunctionExists)
if (IOS)
INCLUDE(CmakeLists_IOS.txt)
@ -85,6 +80,12 @@ set(CMAKE_C_EXTENSIONS OFF)
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
include(CheckLinkerFlag)
include(CheckLibraryExists)
include(CheckFunctionExists)
function (add_c_flag_if_supported flag var)
string(REPLACE "-" "_" supported ${flag}_c)
check_c_compiler_flag(${flag} ${supported})
@ -284,6 +285,7 @@ if(NOT MANUAL_SUBMODULES)
check_submodule(external/googletest)
endif()
check_submodule(external/uWebSockets uSockets)
check_submodule(external/ghc-filesystem)
endif()
endif()
@ -335,6 +337,8 @@ endif()
# elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
# set(BSDI TRUE)
include(cmake/check_for_std_filesystem.cmake)
include_directories(external/rapidjson/include src external)
if(APPLE)
@ -792,10 +796,8 @@ set(Boost_USE_MULTITHREADED TRUE) # Needed for macOS, at least, and won't hurt e
if(BUILD_STATIC_DEPS)
# StaticBuild.cmake sets Boost targets up for us
elseif (WIN32)
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time serialization program_options locale)
else()
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time serialization program_options)
find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system thread serialization program_options)
endif()
set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES})

View File

@ -316,7 +316,7 @@ build_external(boost
CONFIGURE_COMMAND
${CMAKE_COMMAND} -E env ${boost_bootstrap_cxx}
./bootstrap.sh --without-icu --prefix=${DEPS_DESTDIR} --with-toolset=${boost_toolset}
--with-libraries=filesystem,program_options,system,thread,date_time,serialization,locale,atomic
--with-libraries=program_options,system,thread,date_time,serialization
BUILD_COMMAND true
INSTALL_COMMAND
./b2 -d0 variant=release link=static runtime-link=static optimization=speed ${boost_extra}
@ -324,10 +324,7 @@ build_external(boost
--disable-icu --user-config=${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam
install
BUILD_BYPRODUCTS
${DEPS_DESTDIR}/lib/libboost_atomic.a
${DEPS_DESTDIR}/lib/libboost_date_time.a
${DEPS_DESTDIR}/lib/libboost_filesystem.a
${DEPS_DESTDIR}/lib/libboost_locale.a
${DEPS_DESTDIR}/lib/libboost_program_options.a
${DEPS_DESTDIR}/lib/libboost_serialization.a
${DEPS_DESTDIR}/lib/libboost_system.a
@ -338,11 +335,10 @@ add_library(boost_core INTERFACE)
add_dependencies(boost_core INTERFACE boost_external)
target_include_directories(boost_core SYSTEM INTERFACE ${DEPS_DESTDIR}/include)
add_library(Boost::boost ALIAS boost_core)
foreach(boostlib atomic date_time filesystem locale program_options serialization system thread)
foreach(boostlib date_time program_options serialization system thread)
add_static_target(Boost::${boostlib} boost_external libboost_${boostlib}.a)
target_link_libraries(Boost::${boostlib} INTERFACE boost_core)
endforeach()
target_link_libraries(Boost::locale INTERFACE Boost::thread)
set(Boost_FOUND ON)
set(Boost_VERSION ${BOOST_VERSION})

View File

@ -0,0 +1,52 @@
# Figure out if we need -lstdc++fs or -lc++fs and add it to the `filesystem` interface, if needed
# (otherwise just leave it an empty interface library; linking to it will do nothing). The former
# is needed for gcc before v9, and the latter with libc++ before llvm v9. But this gets more
# complicated than just using the compiler, because clang on linux by default uses libstdc++, so
# we'll just give up and see what works.
add_library(filesystem INTERFACE)
set(filesystem_code [[
#include <filesystem>
int main() {
auto cwd = std::filesystem::current_path();
return !cwd.string().empty();
}
]])
if(CMAKE_CXX_COMPILER STREQUAL "AppleClang" AND CMAKE_OSX_DEPLOYMENT_TARGET)
# It seems that check_cxx_source_compiles doesn't respect the CMAKE_OSX_DEPLOYMENT_TARGET, so this
# check would pass on Catalina (10.15) and then later compilation would fail because you aren't
# allowed to use <filesystem> when the deployment target is anything before 10.15.
set(CMAKE_REQUIRED_FLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
endif()
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("${filesystem_code}" filesystem_compiled)
if(filesystem_compiled)
message(STATUS "No extra link flag needed for std::filesystem")
set(filesystem_is_good ON)
else()
foreach(fslib stdc++fs c++fs)
set(CMAKE_REQUIRED_LIBRARIES -l${fslib})
check_cxx_source_compiles("${filesystem_code}" filesystem_compiled_${fslib})
if (filesystem_compiled_${fslib})
message(STATUS "Using -l${fslib} for std::filesystem support")
target_link_libraries(filesystem INTERFACE ${fslib})
set(filesystem_is_good ON)
break()
endif()
endforeach()
endif()
unset(CMAKE_REQUIRED_LIBRARIES)
option(FORCE_GHC_FILESYSTEM "Force ghc::filesystem even when std::filesystem appears to work" OFF)
if(filesystem_is_good AND NOT FORCE_GHC_FILESYSTEM)
message(STATUS "we have std::filesystem")
else()
# Probably broken AF macos
message(STATUS "std::filesystem is not available, apparently this compiler isn't C++17 compliant; falling back to ghc::filesystem")
add_subdirectory(external/ghc-filesystem)
target_link_libraries(filesystem INTERFACE ghc_filesystem)
target_compile_definitions(filesystem INTERFACE USE_GHC_FILESYSTEM)
endif()

View File

@ -1,235 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifndef _FILE_IO_UTILS_H_
#define _FILE_IO_UTILS_H_
#include <fstream>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#ifdef WIN32
#include <windows.h>
#include "string_tools.h"
#endif
// On Windows there is a problem with non-ASCII characters in path and file names
// as far as support by the standard components used is concerned:
// The various file stream classes, e.g. std::ifstream and std::ofstream, are
// part of the GNU C++ Library / libstdc++. On the most basic level they use the
// fopen() call as defined / made accessible to programs compiled within MSYS2
// by the stdio.h header file maintained by the MinGW project.
// The critical point: The implementation of fopen() is part of MSVCRT, the
// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any
// Unicode support.
// Monero code that would want to continue to use the normal file stream classes
// but WITH Unicode support could therefore not solve this problem on its own,
// but 2 different projects from 2 different maintaining groups would need changes
// in this particular direction - something probably difficult to achieve and
// with a long time to wait until all new versions / releases arrive.
// Implemented solution approach: Circumvent the problem by stopping to use std
// file stream classes on Windows and directly use Unicode-capable WIN32 API
// calls. Most of the code doing so is concentrated in this header file here.
namespace epee
{
namespace file_io_utils
{
inline
bool is_file_exist(const std::string& path)
{
boost::filesystem::path p(path);
return boost::filesystem::exists(p);
}
inline
bool save_string_to_file(const std::string& path_to_file, const std::string& str)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD bytes_written;
DWORD bytes_to_write = (DWORD)str.size();
BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL);
CloseHandle(file_handle);
if (bytes_written != bytes_to_write)
result = FALSE;
return result;
#else
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
inline
bool get_file_time(const std::string& path_to_file, time_t& ft)
{
boost::system::error_code ec;
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
if(!ec)
return true;
else
return false;
}
inline
bool set_file_time(const std::string& path_to_file, const time_t& ft)
{
boost::system::error_code ec;
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
if(!ec)
return true;
else
return false;
}
inline
bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
DWORD file_size = GetFileSize(file_handle, NULL);
if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) {
CloseHandle(file_handle);
return false;
}
target_str.resize(file_size);
DWORD bytes_read;
BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL);
CloseHandle(file_handle);
if (bytes_read != file_size)
result = FALSE;
return result;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
std::ifstream::pos_type file_size = fstream.tellg();
if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large
return false;//don't go crazy
size_t file_size_t = static_cast<size_t>(file_size);
target_str.resize(file_size_t);
fstream.seekg (0, std::ios::beg);
fstream.read((char*)target_str.data(), target_str.size());
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
inline
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
{
// No special Windows implementation because so far not used in Monero code
try
{
std::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream << str;
fstream.close();
return true;
}
catch(...)
{
return false;
}
}
inline
bool get_file_size(const std::string& path_to_file, uint64_t &size)
{
#ifdef WIN32
std::wstring wide_path;
try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; }
HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (file_handle == INVALID_HANDLE_VALUE)
return false;
LARGE_INTEGER file_size;
BOOL result = GetFileSizeEx(file_handle, &file_size);
CloseHandle(file_handle);
if (result) {
size = file_size.QuadPart;
}
return size;
#else
try
{
std::ifstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
size = fstream.tellg();
fstream.close();
return true;
}
catch(...)
{
return false;
}
#endif
}
}
}
#endif //_FILE_IO_UTILS_H_

View File

@ -1,34 +0,0 @@
// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the Andrey N. Sabelnikov nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#pragma once
#define BOOST_FILESYSTEM_VERSION 3
#define ENABLE_RELEASE_LOGGING
#include "misc_log_ex.h"

View File

@ -28,7 +28,6 @@
#include <string_view>
#include <charconv>
#include "parserse_base_utils.h"
#include "file_io_utils.h"
#define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100

View File

@ -31,7 +31,6 @@
#include "parserse_base_utils.h"
#include "portable_storage.h"
#include "file_io_utils.h"
namespace epee
{
@ -50,16 +49,6 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool load_t_from_json_file(t_struct& out, const std::string& json_file)
{
std::string f_buff;
if(!file_io_utils::load_file_to_string(json_file, f_buff))
return false;
return load_t_from_json(out, f_buff);
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool store_t_to_json(t_struct& str_in, std::string& json_buff, size_t indent = 0, bool insert_newlines = true)
{
portable_storage ps;
@ -77,14 +66,6 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool store_t_to_json_file(t_struct& str_in, const std::string& fpath)
{
std::string json_buff;
store_t_to_json(str_in, json_buff);
return file_io_utils::save_string_to_file(fpath, json_buff);
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool load_t_from_binary(t_struct& out, const epee::span<const uint8_t> binary_buff)
{
portable_storage ps;
@ -106,16 +87,6 @@ namespace epee
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool load_t_from_binary_file(t_struct& out, const std::string& binary_file)
{
std::string f_buff;
if(!file_io_utils::load_file_to_string(binary_file, f_buff))
return false;
return load_t_from_binary(out, f_buff);
}
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0)
{
portable_storage ps;

View File

@ -322,63 +322,6 @@ POP_WARNINGS
}
//----------------------------------------------------------------------------
bool validate_hex(uint64_t length, const std::string& str);
//----------------------------------------------------------------------------
inline std::string get_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return res;
res = str.substr(pos+1, str.size()-pos);
return res;
}
//----------------------------------------------------------------------------
inline std::string cut_off_extension(const std::string& str)
{
std::string res;
std::string::size_type pos = str.rfind('.');
if(std::string::npos == pos)
return str;
res = str.substr(0, pos);
return res;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
inline std::wstring utf8_to_utf16(const std::string& str)
{
if (str.empty())
return {};
int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0);
if (wstr_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::wstring wstr(wstr_size, wchar_t{});
if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return wstr;
}
inline std::string utf16_to_utf8(const std::wstring& wstr)
{
if (wstr.empty())
return {};
int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL);
if (str_size == 0)
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
std::string str(str_size, char{});
if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL))
{
throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message());
}
return str;
}
#endif
}
}
#endif //_STRING_TOOLS_H_

View File

@ -66,7 +66,7 @@ target_link_libraries(epee
easylogging
PRIVATE
lokimq::lokimq
Boost::filesystem
filesystem
Boost::thread
extra)

View File

@ -37,12 +37,19 @@
#include <ctime>
#include <atomic>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include "string_tools.h"
#include "misc_os_dependent.h"
#include "misc_log_ex.h"
#ifndef USE_GHC_FILESYSTEM
#include <filesystem>
namespace fs { using namespace std::filesystem; }
#else
#include <ghc/filesystem.hpp>
namespace fs = ghc::filesystem;
#endif
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "logging"
@ -82,7 +89,7 @@ std::string mlog_get_default_log_path(const char *default_filename)
else
default_log_file = default_filename;
return (boost::filesystem::path(default_log_folder) / boost::filesystem::path(default_log_file)).string();
return (fs::u8path(default_log_folder) / fs::u8path(default_log_file)).u8string();
}
static void mlog_set_common_prefix()
@ -173,52 +180,27 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s
}
if (max_log_files != 0)
{
std::vector<boost::filesystem::path> found_files;
const boost::filesystem::directory_iterator end_itr;
const boost::filesystem::path filename_base_path(filename_base);
const boost::filesystem::path parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : ".";
for (boost::filesystem::directory_iterator iter(parent_path); iter != end_itr; ++iter)
std::vector<fs::path> found_files;
const auto filename_base_path = fs::u8path(filename_base);
const auto parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : fs::path(".");
for (const auto& p : fs::directory_iterator{parent_path})
{
const std::string filename = iter->path().string();
const std::string filename = p.path().u8string();
if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0)
{
found_files.push_back(iter->path());
}
found_files.push_back(p.path());
}
if (found_files.size() >= max_log_files)
{
std::sort(found_files.begin(), found_files.end(), [](const boost::filesystem::path &a, const boost::filesystem::path &b) {
boost::system::error_code ec;
std::time_t ta = boost::filesystem::last_write_time(boost::filesystem::path(a), ec);
if (ec)
{
MERROR("Failed to get timestamp from " << a << ": " << ec);
ta = std::time(nullptr);
}
std::time_t tb = boost::filesystem::last_write_time(boost::filesystem::path(b), ec);
if (ec)
{
MERROR("Failed to get timestamp from " << b << ": " << ec);
tb = std::time(nullptr);
}
static_assert(std::is_integral<time_t>(), "bad time_t");
return ta < tb;
std::sort(found_files.begin(), found_files.end(), [](auto& a, auto& b) {
std::error_code ec;
return fs::last_write_time(a, ec) < fs::last_write_time(b, ec);
});
for (size_t i = 0; i <= found_files.size() - max_log_files; ++i)
{
try
{
boost::system::error_code ec;
boost::filesystem::remove(found_files[i], ec);
if (ec)
{
MERROR("Failed to remove " << found_files[i] << ": " << ec);
}
}
catch (const std::exception &e)
{
MERROR("Failed to remove " << found_files[i] << ": " << e.what());
}
std::error_code ec;
if (!fs::remove(found_files[i], ec))
MERROR("Failed to remove " << found_files[i] << ": " << ec.message());
}
}
}

1
external/ghc-filesystem vendored Submodule

@ -0,0 +1 @@
Subproject commit 7e37433f318488ae4bc80f80e12df12a01579874

View File

@ -37,7 +37,7 @@ target_link_libraries(blockchain_db
common
ringct
lmdb
Boost::filesystem
filesystem
Boost::thread
extra)

View File

@ -34,6 +34,7 @@
#include <exception>
#include <boost/program_options.hpp>
#include "common/command_line.h"
#include "common/fs.h"
#include "crypto/hash.h"
#include "cryptonote_basic/blobdatatype.h"
#include "cryptonote_basic/cryptonote_basic.h"
@ -589,10 +590,6 @@ public:
* The subclass implementing this will handle all file opening/creation,
* and is responsible for maintaining its state.
*
* The parameter <filename> may not refer to a file name, necessarily, but
* could be an IP:PORT for a database which needs it, and so on. Calling it
* <filename> is convenient and should be descriptive enough, however.
*
* For now, db_flags are
* specific to the subclass being instantiated. This is subject to change,
* and the db_flags parameter may be deprecated.
@ -600,10 +597,10 @@ public:
* If any of this cannot be done, the subclass should throw the corresponding
* subclass of DB_EXCEPTION
*
* @param filename a string referring to the BlockchainDB to open
* @param filename a path referring to the BlockchainDB to open
* @param db_flags flags relevant to how to open/use the BlockchainDB
*/
virtual void open(const std::string& filename, cryptonote::network_type nettype, const int db_flags = 0) = 0;
virtual void open(const fs::path& filename, cryptonote::network_type nettype, const int db_flags = 0) = 0;
/**
* @brief Gets the current open/ready state of the BlockchainDB
@ -665,7 +662,7 @@ public:
*
* @return a list of filenames
*/
virtual std::vector<std::string> get_filenames() const = 0;
virtual std::vector<fs::path> get_filenames() const = 0;
/**
* @brief remove file(s) storing the database
@ -679,7 +676,7 @@ public:
*
* @return true if the operation is succesfull
*/
virtual bool remove_data_file(const std::string& folder) const = 0;
virtual bool remove_data_file(const fs::path& folder) const = 0;
// return the name of the folder the db's file(s) should reside in
/**

View File

@ -28,7 +28,6 @@
#include "db_lmdb.h"
#include <boost/filesystem.hpp>
#include <boost/format.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/endian/conversion.hpp>
@ -36,7 +35,6 @@
#include <cstring>
#include "string_tools.h"
#include "file_io_utils.h"
#include "common/file.h"
#include "common/pruning.h"
#include "common/hex.h"
@ -608,8 +606,7 @@ void BlockchainLMDB::do_resize(uint64_t increase_size)
// check disk capacity
try
{
boost::filesystem::path path(m_folder);
boost::filesystem::space_info si = boost::filesystem::space(path);
auto si = fs::space(m_folder);
if(si.available < add_size)
{
MERROR("!! WARNING: Insufficient free space to extend database !!: " <<
@ -957,7 +954,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH);
if (result == 0) {
txindex *tip = (txindex *)val_h.mv_data;
throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx id ").append(boost::lexical_cast<std::string>(tip->data.tx_id)).append(")").c_str()));
throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx id ").append(std::to_string(tip->data.tx_id)).append(")").c_str()));
} else if (result != MDB_NOTFOUND) {
throw1(DB_ERROR(lmdb_error(std::string("Error checking if tx index exists for tx hash ") + epee::string_tools::pod_to_hex(tx_hash) + ": ", result).c_str()));
}
@ -1243,12 +1240,12 @@ void BlockchainLMDB::remove_output(const uint64_t amount, const uint64_t& out_in
}
result = mdb_cursor_del(m_cur_output_txs, 0);
if (result)
throw0(DB_ERROR(lmdb_error(std::string("Error deleting output index ").append(boost::lexical_cast<std::string>(out_index).append(": ")).c_str(), result).c_str()));
throw0(DB_ERROR(lmdb_error(std::string("Error deleting output index ").append(std::to_string(out_index).append(": ")).c_str(), result).c_str()));
// now delete the amount
result = mdb_cursor_del(m_cur_output_amounts, 0);
if (result)
throw0(DB_ERROR(lmdb_error(std::string("Error deleting amount for output index ").append(boost::lexical_cast<std::string>(out_index).append(": ")).c_str(), result).c_str()));
throw0(DB_ERROR(lmdb_error(std::string("Error deleting amount for output index ").append(std::to_string(out_index).append(": ")).c_str(), result).c_str()));
}
void BlockchainLMDB::prune_outputs(uint64_t amount)
@ -1375,7 +1372,7 @@ BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB()
m_hardfork = nullptr;
}
void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type nettype, const int db_flags)
void BlockchainLMDB::open(const fs::path& filename, cryptonote::network_type nettype, const int db_flags)
{
int result;
int mdb_flags = MDB_NORDAHEAD;
@ -1385,24 +1382,23 @@ void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type
if (m_open)
throw0(DB_OPEN_FAILURE("Attempted to open db, but it's already open"));
boost::filesystem::path direc(filename);
if (boost::filesystem::exists(direc))
if (fs::exists(filename))
{
if (!boost::filesystem::is_directory(direc))
if (!fs::is_directory(filename))
throw0(DB_OPEN_FAILURE("LMDB needs a directory path, but a file was passed"));
}
else
{
if (!boost::filesystem::create_directories(direc))
throw0(DB_OPEN_FAILURE(std::string("Failed to create directory ").append(filename).c_str()));
if (std::error_code ec; !fs::create_directories(filename, ec))
throw0(DB_OPEN_FAILURE("Failed to create directory " + filename.u8string()));
}
// check for existing LMDB files in base directory
boost::filesystem::path old_files = direc.parent_path();
if (boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_FILENAME)
|| boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME))
auto old_files = filename.parent_path();
if (fs::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_FILENAME)
|| fs::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME))
{
LOG_PRINT_L0("Found existing LMDB files in " << old_files.string());
LOG_PRINT_L0("Found existing LMDB files in " << old_files.u8string());
LOG_PRINT_L0("Move " << CRYPTONOTE_BLOCKCHAINDATA_FILENAME << " and/or " << CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME << " to " << filename << ", or delete them, and then restart");
throw DB_ERROR("Database could not be opened");
}
@ -1437,7 +1433,9 @@ void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type
if (db_flags & DBF_SALVAGE)
mdb_flags |= MDB_PREVSNAPSHOT;
if (auto result = mdb_env_open(m_env, filename.c_str(), mdb_flags, 0644))
// This .string() is probably just going to hard fail on Windows with non-ASCII unicode filenames,
// but lmdb doesn't support anything else (and so really we're just hitting an underlying lmdb bug).
if (auto result = mdb_env_open(m_env, filename.string().c_str(), mdb_flags, 0644))
throw0(DB_ERROR(lmdb_error("Failed to open lmdb environment: ", result).c_str()));
MDB_envinfo mei;
@ -1705,28 +1703,18 @@ void BlockchainLMDB::reset()
m_cum_count = 0;
}
std::vector<std::string> BlockchainLMDB::get_filenames() const
std::vector<fs::path> BlockchainLMDB::get_filenames() const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
std::vector<std::string> filenames;
boost::filesystem::path datafile(m_folder);
datafile /= CRYPTONOTE_BLOCKCHAINDATA_FILENAME;
boost::filesystem::path lockfile(m_folder);
lockfile /= CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME;
filenames.push_back(datafile.string());
filenames.push_back(lockfile.string());
return filenames;
return {{m_folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME, m_folder / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME}};
}
bool BlockchainLMDB::remove_data_file(const std::string& folder) const
bool BlockchainLMDB::remove_data_file(const fs::path& folder) const
{
const std::string filename = folder + "/data.mdb";
auto filename = folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME;
try
{
boost::filesystem::remove(filename);
fs::remove(filename);
}
catch (const std::exception &e)
{
@ -4747,12 +4735,7 @@ bool BlockchainLMDB::is_read_only() const
uint64_t BlockchainLMDB::get_database_size() const
{
uint64_t size = 0;
boost::filesystem::path datafile(m_folder);
datafile /= CRYPTONOTE_BLOCKCHAINDATA_FILENAME;
if (!epee::file_io_utils::get_file_size(datafile.string(), size))
size = 0;
return size;
return fs::file_size(m_folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME);
}
void BlockchainLMDB::fixup(cryptonote::network_type nettype)

View File

@ -31,6 +31,7 @@
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_basic/blobdatatype.h" // for type blobdata
#include "ringct/rctTypes.h"
#include "common/fs.h"
#include <boost/thread/thread.hpp>
#include <boost/thread/tss.hpp>
@ -177,7 +178,7 @@ public:
BlockchainLMDB(bool batch_transactions=true);
~BlockchainLMDB();
void open(const std::string& filename, cryptonote::network_type nettype, const int mdb_flags=0) override;
void open(const fs::path& filename, cryptonote::network_type nettype, const int mdb_flags=0) override;
void close() override;
@ -187,9 +188,9 @@ public:
void reset() override;
std::vector<std::string> get_filenames() const override;
std::vector<fs::path> get_filenames() const override;
bool remove_data_file(const std::string& folder) const override;
bool remove_data_file(const fs::path& folder) const override;
std::string get_db_name() const override;
@ -490,7 +491,7 @@ private:
mutable uint64_t m_cum_size; // used in batch size estimation
mutable unsigned int m_cum_count;
std::string m_folder;
fs::path m_folder;
mdb_txn_safe* m_write_txn; // may point to either a short-lived txn or a batch txn
mdb_txn_safe* m_write_batch_txn; // persist batch txn outside of BlockchainLMDB
boost::thread::id m_writer;

View File

@ -35,6 +35,7 @@
#include <map>
#include "blockchain_db.h"
#include "cryptonote_core/service_node_list.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
namespace cryptonote
{
@ -42,13 +43,13 @@ namespace cryptonote
class BaseTestDB: public cryptonote::BlockchainDB {
public:
BaseTestDB() {}
virtual void open(const std::string& filename, network_type nettype = FAKECHAIN, const int db_flags = 0) override { }
virtual void open(const fs::path& filename, network_type nettype = FAKECHAIN, const int db_flags = 0) override { }
virtual void close() override {}
virtual void sync() override {}
virtual void safesyncmode(const bool onoff) override {}
virtual void reset() override {}
virtual std::vector<std::string> get_filenames() const override { return std::vector<std::string>(); }
virtual bool remove_data_file(const std::string& folder) const override { return true; }
virtual std::vector<fs::path> get_filenames() const override { return {}; }
virtual bool remove_data_file(const fs::path& folder) const override { return true; }
virtual std::string get_db_name() const override { return std::string(); }
virtual void lock() override { }
virtual bool try_lock() override { return true; }

View File

@ -32,7 +32,7 @@ target_link_libraries(blockchain_tools_common_libs INTERFACE
cryptonote_core
blockchain_db
version
Boost::filesystem
filesystem
Boost::program_options
extra)
@ -110,7 +110,7 @@ target_link_libraries(blockchain_stats PRIVATE blockchain_tools_common_libs)
if (TARGET sodium_vendor OR NOT SODIUM_VERSION VERSION_LESS 1.0.17)
loki_add_executable(sn_key_tool "loki-sn-keys" sn_key_tool.cpp)
target_link_libraries(sn_key_tool PRIVATE sodium lokimq)
target_link_libraries(sn_key_tool PRIVATE sodium lokimq filesystem)
else()
message(STATUS "Not building loki-sn-keys tool (requires libsodium >= 1.0.17)")
endif()

View File

@ -32,13 +32,13 @@
#include <unordered_map>
#include <unordered_set>
#include <boost/filesystem.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include "common/unordered_containers_boost_serialization.h"
#include "common/command_line.h"
#include "common/varint.h"
#include "common/signal_handler.h"
#include "common/fs.h"
#include "serialization/boost_std_variant.h"
#include "cryptonote_basic/cryptonote_boost_serialization.h"
#include "cryptonote_core/cryptonote_core.h"
@ -337,8 +337,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -447,7 +445,7 @@ int main(int argc, char* argv[])
}
LOG_PRINT_L0("database: LMDB");
const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string();
fs::path filename = fs::u8path(opt_data_dir) / db->get_db_name();
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try
@ -468,9 +466,9 @@ int main(int argc, char* argv[])
ancestry_state_t state;
const std::string state_file_path = (boost::filesystem::path(opt_data_dir) / "ancestry-state.bin").string();
fs::path state_file_path = fs::u8path(opt_data_dir) / "ancestry-state.bin";
LOG_PRINT_L0("Loading state data from " << state_file_path);
std::ifstream state_data_in;
fs::ifstream state_data_in;
state_data_in.open(state_file_path, std::ios_base::binary | std::ios_base::in);
if (!state_data_in.fail())
{

View File

@ -132,20 +132,19 @@ static bool parse_db_sync_mode(std::string db_sync_mode)
return true;
}
static std::string get_default_db_path()
static fs::path get_default_db_path()
{
boost::filesystem::path dir = tools::get_default_data_dir();
// remove .loki, replace with .shared-ringdb
dir = dir.remove_filename();
dir /= ".shared-ringdb";
return dir.string();
fs::path p = tools::get_default_data_dir();
p.replace_filename(".shared-ringdb");
return p;
}
static std::string get_cache_filename(boost::filesystem::path filename)
static fs::path get_cache_filename(fs::path filename)
{
if (!boost::filesystem::is_directory(filename))
if (!fs::is_directory(filename))
filename.remove_filename();
return filename.string();
return filename;
}
static int compare_hash32(const MDB_val *a, const MDB_val *b)
@ -202,11 +201,10 @@ static int resize_env(const char *db_path)
{
try
{
boost::filesystem::path path(db_path);
boost::filesystem::space_info si = boost::filesystem::space(path);
auto si = fs::space(fs::u8path(db_path));
if(si.available < needed)
{
MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available >> 20L) << " MB available");
MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available / 1000000) << " MB available");
return ENOSPC;
}
}
@ -221,7 +219,7 @@ static int resize_env(const char *db_path)
return mdb_env_set_mapsize(env, mapsize);
}
static void init(std::string cache_filename)
static void init(fs::path cache_filename)
{
MDB_txn *txn;
bool tx_active = false;
@ -229,7 +227,8 @@ static void init(std::string cache_filename)
MINFO("Creating spent output cache in " << cache_filename);
tools::create_directories_if_necessary(cache_filename);
if (std::error_code ec; !fs::create_directories(cache_filename, ec))
MWARNING("Failed to create output cache directory " << cache_filename << ": " << ec.message());
int flags = 0;
if (db_flags & DBF_FAST)
@ -241,10 +240,10 @@ static void init(std::string cache_filename)
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(env, 7);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = get_cache_filename(cache_filename);
dbr = mdb_env_open(env, actual_filename.c_str(), flags, 0664);
auto actual_filename = get_cache_filename(cache_filename);
dbr = mdb_env_open(env, actual_filename.string().c_str(), flags, 0664);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ actual_filename.string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, 0, &txn);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -330,7 +329,7 @@ static std::vector<uint64_t> decompress_ring(const std::string &s)
return ring;
}
static bool for_all_transactions(const std::string &filename, uint64_t &start_idx, uint64_t &n_txes, const std::function<bool(const cryptonote::transaction_prefix&)> &f)
static bool for_all_transactions(const fs::path& filename, uint64_t& start_idx, uint64_t& n_txes, const std::function<bool(const cryptonote::transaction_prefix&)>& f)
{
MDB_env *env;
MDB_dbi dbi;
@ -345,10 +344,9 @@ static bool for_all_transactions(const std::string &filename, uint64_t &start_id
if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(env, 2);
if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = filename;
dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664);
dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664);
if (dbr) throw std::runtime_error("Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ filename.u8string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -411,7 +409,7 @@ static bool for_all_transactions(const std::string &filename, uint64_t &start_id
return fret;
}
static bool for_all_transactions(const std::string &filename, const uint64_t &start_idx, uint64_t &n_txes, const std::function<bool(bool, uint64_t, const cryptonote::transaction_prefix&)> &f)
static bool for_all_transactions(const fs::path& filename, const uint64_t& start_idx, uint64_t& n_txes, const std::function<bool(bool, uint64_t, const cryptonote::transaction_prefix&)>& f)
{
MDB_env *env;
MDB_dbi dbi_blocks, dbi_txs;
@ -426,14 +424,13 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st
if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(env, 3);
if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = filename;
dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664);
dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664);
if (dbr) throw std::runtime_error("Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ filename.u8string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){if (tx_active) mdb_txn_abort(txn);});
LOKI_DEFER { if (tx_active) mdb_txn_abort(txn); };
tx_active = true;
dbr = mdb_dbi_open(txn, "blocks", MDB_INTEGERKEY, &dbi_blocks);
@ -520,7 +517,7 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st
return fret;
}
static uint64_t find_first_diverging_transaction(const std::string &first_filename, const std::string &second_filename)
static uint64_t find_first_diverging_transaction(const fs::path& first_filename, const fs::path& second_filename)
{
MDB_env *env[2];
MDB_dbi dbi[2];
@ -543,10 +540,10 @@ static uint64_t find_first_diverging_transaction(const std::string &first_filena
if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(env[i], 2);
if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = i ? second_filename : first_filename;
dbr = mdb_env_open(env[i], actual_filename.c_str(), 0, 0664);
const fs::path& actual_filename = i ? second_filename : first_filename;
dbr = mdb_env_open(env[i], actual_filename.string().c_str(), 0, 0664);
if (dbr) throw std::runtime_error("Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ actual_filename.u8string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env[i], NULL, MDB_RDONLY, &txn[i]);
if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -951,7 +948,7 @@ static void inc_stat(MDB_txn *txn, const char *key)
set_stat(txn, key, data);
}
static void open_db(const std::string &filename, MDB_env **env, MDB_txn **txn, MDB_cursor **cur, MDB_dbi *dbi)
static void open_db(const fs::path& filename, MDB_env** env, MDB_txn** txn, MDB_cursor** cur, MDB_dbi* dbi)
{
tools::create_directories_if_necessary(filename);
@ -965,11 +962,10 @@ static void open_db(const std::string &filename, MDB_env **env, MDB_txn **txn, M
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(*env, 1);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = filename;
MINFO("Opening monero blockchain at " << actual_filename);
dbr = mdb_env_open(*env, actual_filename.c_str(), flags, 0664);
MINFO("Opening loki blockchain at " << filename);
dbr = mdb_env_open(*env, filename.string().c_str(), flags, 0664);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ filename.u8string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(*env, NULL, MDB_RDONLY, txn);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -1014,7 +1010,7 @@ static void get_num_outputs(MDB_txn *txn, MDB_cursor *cur, MDB_dbi dbi, uint64_t
pre_rct = s.ms_entries - rct;
}
static crypto::hash get_genesis_block_hash(const std::string &filename)
static crypto::hash get_genesis_block_hash(const fs::path& filename)
{
MDB_env *env;
MDB_dbi dbi;
@ -1026,10 +1022,9 @@ static crypto::hash get_genesis_block_hash(const std::string &filename)
if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
dbr = mdb_env_set_maxdbs(env, 1);
if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
const std::string actual_filename = filename;
dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664);
dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664);
if (dbr) throw std::runtime_error("Failed to open rings database file '"
+ actual_filename + "': " + std::string(mdb_strerror(dbr)));
+ filename.u8string() + "': " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -1051,13 +1046,18 @@ static crypto::hash get_genesis_block_hash(const std::string &filename)
return genesis_block_hash;
}
static std::vector<std::pair<uint64_t, uint64_t>> load_outputs(const std::string &filename)
static std::vector<std::pair<uint64_t, uint64_t>> load_outputs(const fs::path& filename)
{
std::vector<std::pair<uint64_t, uint64_t>> outputs;
uint64_t amount = std::numeric_limits<uint64_t>::max();
FILE *f;
f = fopen(filename.c_str(), "r");
FILE* f =
#ifdef _WIN32
_wfopen(filename.c_str(), L"r");
#else
fopen(filename.c_str(), "r");
#endif
if (!f)
{
MERROR("Failed to load outputs from " << filename << ": " << strerror(errno));
@ -1108,9 +1108,15 @@ static std::vector<std::pair<uint64_t, uint64_t>> load_outputs(const std::string
return outputs;
}
static bool export_spent_outputs(MDB_cursor *cur, const std::string &filename)
static bool export_spent_outputs(MDB_cursor* cur, const fs::path& filename)
{
FILE *f = fopen(filename.c_str(), "w");
FILE* f =
#ifdef _WIN32
_wfopen(filename.c_str(), L"w");
#else
fopen(filename.c_str(), "w");
#endif
if (!f)
{
MERROR("Failed to open " << filename << ": " << strerror(errno));
@ -1172,15 +1178,13 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
po::options_description desc_cmd_sett("Command line options and settings options", opt_size.first, opt_size.second);
const command_line::arg_descriptor<std::string> arg_blackball_db_dir = {
"spent-output-db-dir", "Specify spent output database directory",
get_default_db_path(),
get_default_db_path().u8string(),
};
const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
const command_line::arg_descriptor<bool> arg_rct_only = {"rct-only", "Only work on ringCT outputs", false};
@ -1242,7 +1246,7 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Starting...");
output_file_path = command_line::get_arg(vm, arg_blackball_db_dir);
fs::path output_file_path = fs::u8path(command_line::get_arg(vm, arg_blackball_db_dir));
bool opt_rct_only = command_line::get_arg(vm, arg_rct_only);
bool opt_check_subsets = command_line::get_arg(vm, arg_check_subsets);
bool opt_verbose = command_line::get_arg(vm, arg_verbose);
@ -1260,7 +1264,9 @@ int main(int argc, char* argv[])
return 1;
}
const std::vector<std::string> inputs = command_line::get_arg(vm, arg_inputs);
std::vector<fs::path> inputs;
for (auto& in : command_line::get_arg(vm, arg_inputs))
inputs.push_back(fs::u8path(in));
if (inputs.empty())
{
LOG_PRINT_L0("No inputs given");
@ -1274,7 +1280,7 @@ int main(int argc, char* argv[])
core_storage[n] = &(blockchain_objects->m_blockchain);
}
const std::string cache_dir = (output_file_path / "spent-outputs-cache").string();
fs::path cache_dir = output_file_path / "spent-outputs-cache";
init(cache_dir);
LOG_PRINT_L0("Scanning for spent outputs...");
@ -1290,7 +1296,7 @@ int main(int argc, char* argv[])
stop_requested = true;
});
int dbr = resize_env(cache_dir.c_str());
int dbr = resize_env(cache_dir.string().c_str());
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr)));
// open first db
@ -1395,7 +1401,7 @@ int main(int argc, char* argv[])
for (size_t n = 0; n < inputs.size(); ++n)
{
const std::string canonical = boost::filesystem::canonical(inputs[n]).string();
const std::string canonical = fs::canonical(inputs[n]).u8string();
uint64_t start_idx = get_processed_txidx(canonical);
if (n > 0 && start_idx == 0)
{
@ -1410,10 +1416,9 @@ int main(int argc, char* argv[])
dbr = mdb_cursor_open(txn, dbi_spent, &cur);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open LMDB cursor: " + std::string(mdb_strerror(dbr)));
size_t records = 0;
const std::string filename = inputs[n];
std::vector<std::pair<uint64_t, uint64_t>> blackballs;
uint64_t n_txes;
for_all_transactions(filename, start_idx, n_txes, [&](const cryptonote::transaction_prefix &tx)->bool
for_all_transactions(inputs[n], start_idx, n_txes, [&](const cryptonote::transaction_prefix &tx)->bool
{
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
for (const auto &in: tx.vin)
@ -1573,7 +1578,7 @@ int main(int argc, char* argv[])
mdb_cursor_close(cur);
dbr = mdb_txn_commit(txn);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to commit txn creating/opening database: " + std::string(mdb_strerror(dbr)));
int dbr = resize_env(cache_dir.c_str());
int dbr = resize_env(cache_dir.string().c_str());
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, 0, &txn);
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@ -1613,7 +1618,7 @@ int main(int argc, char* argv[])
{
LOG_PRINT_L0("Secondary pass on " << work_spent.size() << " spent outputs");
int dbr = resize_env(cache_dir.c_str());
int dbr = resize_env(cache_dir.string().c_str());
CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr)));
MDB_txn *txn;

View File

@ -49,8 +49,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -98,7 +96,6 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Starting...");
std::string opt_data_dir = command_line::get_arg(vm, cryptonote::arg_data_dir);
bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on);
bool opt_devnet = command_line::get_arg(vm, cryptonote::arg_devnet_on);
network_type net_type = opt_testnet ? TESTNET : opt_devnet ? DEVNET : MAINNET;
@ -132,7 +129,7 @@ int main(int argc, char* argv[])
}
LOG_PRINT_L0("database: LMDB");
const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string();
const fs::path filename = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)) / db->get_db_name();
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try

View File

@ -51,8 +51,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -111,14 +109,13 @@ int main(int argc, char* argv[])
}
bool opt_blocks_dat = command_line::get_arg(vm, arg_blocks_dat);
std::string m_config_folder;
m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir);
auto config_folder = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir));
fs::path output_file_path;
if (command_line::has_arg(vm, arg_output_file))
output_file_path = boost::filesystem::path(command_line::get_arg(vm, arg_output_file));
output_file_path = fs::u8path(command_line::get_arg(vm, arg_output_file));
else
output_file_path = boost::filesystem::path(m_config_folder) / "export" / BLOCKCHAIN_RAW;
output_file_path = config_folder / "export" / BLOCKCHAIN_RAW;
LOG_PRINT_L0("Export output file: " << output_file_path.string());
LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)");
@ -132,9 +129,7 @@ int main(int argc, char* argv[])
}
LOG_PRINT_L0("database: LMDB");
boost::filesystem::path folder(m_config_folder);
folder /= db->get_db_name();
const std::string filename = folder.string();
auto filename = config_folder / db->get_db_name();
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try

View File

@ -32,7 +32,6 @@
#include <algorithm>
#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <unistd.h>
#include "cryptonote_protocol/quorumnet.h"
@ -42,7 +41,6 @@
#include "blocks/blocks.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "serialization/binary_utils.h"
#include "include_base_utils.h"
#include "cryptonote_core/cryptonote_core.h"
#undef LOKI_DEFAULT_LOG_CATEGORY
@ -210,18 +208,16 @@ int check_flush(cryptonote::core &core, std::vector<block_complete_entry> &block
return 0;
}
int import_from_file(cryptonote::core& core, const std::string& import_file_path, uint64_t block_stop=0)
int import_from_file(cryptonote::core& core, const fs::path& import_file_path, uint64_t block_stop=0)
{
// Reset stats, in case we're using newly created db, accumulating stats
// from addition of genesis block.
// This aligns internal db counts with importer counts.
core.get_blockchain_storage().get_db().reset_stats();
boost::filesystem::path fs_import_file_path(import_file_path);
boost::system::error_code ec;
if (!boost::filesystem::exists(fs_import_file_path, ec))
if (std::error_code ec; !fs::exists(import_file_path, ec))
{
MFATAL("bootstrap file not found: " << fs_import_file_path);
MFATAL("bootstrap file not found: " << import_file_path);
return false;
}
@ -542,8 +538,6 @@ int main(int argc, char* argv[])
tools::on_startup();
std::string import_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -653,14 +647,12 @@ int main(int argc, char* argv[])
MINFO("Starting...");
boost::filesystem::path fs_import_file_path;
fs::path import_file_path;
if (command_line::has_arg(vm, arg_input_file))
fs_import_file_path = boost::filesystem::path(command_line::get_arg(vm, arg_input_file));
import_file_path = fs::u8path(command_line::get_arg(vm, arg_input_file));
else
fs_import_file_path = boost::filesystem::path(m_config_folder) / "export" / BLOCKCHAIN_RAW;
import_file_path = fs_import_file_path.string();
import_file_path = fs::u8path(m_config_folder) / "export" / BLOCKCHAIN_RAW;
if (command_line::has_arg(vm, arg_count_blocks))
{

View File

@ -31,6 +31,7 @@
#include "common/command_line.h"
#include "common/pruning.h"
#include "common/string_util.h"
#include "common/fs.h"
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_core/blockchain.h"
#include "blockchain_db/blockchain_db.h"
@ -46,21 +47,21 @@
namespace po = boost::program_options;
using namespace cryptonote;
static std::string db_path;
static fs::path db_path;
// default to fast:1
static uint64_t records_per_sync = 128;
static const size_t slack = 512 * 1024 * 1024;
static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name)
static std::error_code replace_file(const fs::path& replacement_name, const fs::path& replaced_name)
{
std::error_code ec = tools::replace_file(replacement_name.string(), replaced_name.string());
std::error_code ec = fs::rename(replacement_name, replaced_name);
if (ec)
MERROR("Error renaming " << replacement_name << " to " << replaced_name << ": " << ec.message());
return ec;
}
static void open(MDB_env *&env, const boost::filesystem::path &path, uint64_t db_flags, bool readonly)
static void open(MDB_env *&env, const fs::path &path, uint64_t db_flags, bool readonly)
{
int dbr;
int flags = 0;
@ -90,8 +91,7 @@ static void add_size(MDB_env *env, uint64_t bytes)
{
try
{
boost::filesystem::path path(db_path);
boost::filesystem::space_info si = boost::filesystem::space(path);
auto si = fs::space(db_path);
if(si.available < bytes)
{
MERROR("!! WARNING: Insufficient free space to extend database !!: " <<
@ -443,8 +443,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -523,7 +521,7 @@ int main(int argc, char* argv[])
// tx_memory_pool, Blockchain's constructor takes tx_memory_pool object.
MINFO("Initializing source blockchain (BlockchainDB)");
std::array<Blockchain *, 2> core_storage;
boost::filesystem::path paths[2];
fs::path paths[2];
bool already_pruned = false;
for (size_t n = 0; n < core_storage.size(); ++n)
{
@ -539,10 +537,10 @@ int main(int argc, char* argv[])
if (n == 1)
{
paths[1] = boost::filesystem::path(data_dir) / (db->get_db_name() + "-pruned");
if (boost::filesystem::exists(paths[1]))
paths[1] = fs::u8path(data_dir) / (db->get_db_name() + "-pruned");
if (fs::exists(paths[1]))
{
if (!boost::filesystem::is_directory(paths[1]))
if (!fs::is_directory(paths[1]))
{
MERROR("LMDB needs a directory path, but a file was passed: " << paths[1].string());
return 1;
@ -550,17 +548,17 @@ int main(int argc, char* argv[])
}
else
{
if (!boost::filesystem::create_directories(paths[1]))
if (!fs::create_directories(paths[1]))
{
MERROR("Failed to create directory: " << paths[1].string());
return 1;
}
}
db_path = paths[1].string();
db_path = paths[1];
}
else
{
paths[0] = boost::filesystem::path(data_dir) / db->get_db_name();
paths[0] = fs::u8path(data_dir) / db->get_db_name();
}
MINFO("Loading blockchain from folder " << paths[n] << " ...");
@ -627,7 +625,9 @@ int main(int argc, char* argv[])
close(env0);
MINFO("Swapping databases, pre-pruning blockchain will be left in " << paths[0].string() + "-old and can be removed if desired");
if (replace_file(paths[0].string(), paths[0].string() + "-old") || replace_file(paths[1].string(), paths[0].string()))
fs::path old = paths[0];
old += "-old";
if (replace_file(paths[0], old) || replace_file(paths[1], paths[0]))
{
MERROR("Blockchain pruned OK, but renaming failed");
return 1;

View File

@ -44,13 +44,18 @@
namespace po = boost::program_options;
using namespace cryptonote;
static std::map<uint64_t, uint64_t> load_outputs(const std::string &filename)
static std::map<uint64_t, uint64_t> load_outputs(const fs::path& filename)
{
std::map<uint64_t, uint64_t> outputs;
uint64_t amount = std::numeric_limits<uint64_t>::max();
FILE *f;
f = fopen(filename.c_str(), "r");
FILE *f =
#ifdef _WIN32
_wfopen(filename.c_str(), L"r");
#else
fopen(filename.c_str(), "r");
#endif
if (!f)
{
MERROR("Failed to load outputs from " << filename << ": " << strerror(errno));
@ -154,14 +159,13 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Starting...");
std::string opt_data_dir = command_line::get_arg(vm, cryptonote::arg_data_dir);
bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on);
bool opt_devnet = command_line::get_arg(vm, cryptonote::arg_devnet_on);
network_type net_type = opt_testnet ? TESTNET : opt_devnet ? DEVNET : MAINNET;
bool opt_verbose = command_line::get_arg(vm, arg_verbose);
bool opt_dry_run = command_line::get_arg(vm, arg_dry_run);
const std::string input = command_line::get_arg(vm, arg_input);
const auto input = fs::u8path(command_line::get_arg(vm, arg_input));
LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)");
blockchain_objects_t blockchain_objects = {};
@ -173,7 +177,7 @@ int main(int argc, char* argv[])
throw std::runtime_error("Failed to initialize a database");
}
const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string();
const fs::path filename = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)) / db->get_db_name();
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try

View File

@ -57,8 +57,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -133,7 +131,7 @@ int main(int argc, char* argv[])
throw std::runtime_error("Failed to initialize a database");
}
const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string();
const fs::path filename = fs::u8path(opt_data_dir) / db->get_db_name();
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try

View File

@ -82,8 +82,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
auto opt_size = command_line::boost_option_sizes();
po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second);
@ -160,7 +158,7 @@ int main(int argc, char* argv[])
}
LOG_PRINT_L0("database: LMDB");
const std::string filename = input;
const fs::path filename = fs::u8path(input);
LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
try

View File

@ -43,14 +43,14 @@ namespace
bool BlocksdatFile::open_writer(const boost::filesystem::path& file_path, uint64_t block_stop)
bool BlocksdatFile::open_writer(const fs::path& file_path, uint64_t block_stop)
{
const boost::filesystem::path dir_path = file_path.parent_path();
const fs::path dir_path = file_path.parent_path();
if (!dir_path.empty())
{
if (boost::filesystem::exists(dir_path))
if (fs::exists(dir_path))
{
if (!boost::filesystem::is_directory(dir_path))
if (!fs::is_directory(dir_path))
{
MFATAL("export directory path is a file: " << dir_path);
return false;
@ -58,7 +58,7 @@ bool BlocksdatFile::open_writer(const boost::filesystem::path& file_path, uint64
}
else
{
if (!boost::filesystem::create_directory(dir_path))
if (!fs::create_directory(dir_path))
{
MFATAL("Failed to create directory " << dir_path);
return false;
@ -124,7 +124,7 @@ bool BlocksdatFile::close()
}
bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, fs::path& output_file, uint64_t requested_block_stop)
{
uint64_t num_blocks_written = 0;
m_blockchain_storage = _blockchain_storage;

View File

@ -32,8 +32,6 @@
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/cryptonote_boost_serialization.h"
@ -47,6 +45,7 @@
#include <atomic>
#include "common/command_line.h"
#include "common/fs.h"
#include "version.h"
#include "blockchain_utilities.h"
@ -60,7 +59,7 @@ class BlocksdatFile
public:
bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0);
fs::path& output_file, uint64_t use_block_height=0);
protected:
@ -69,7 +68,7 @@ protected:
std::ofstream * m_raw_data_file;
// open export file for write
bool open_writer(const boost::filesystem::path& file_path, uint64_t block_stop);
bool open_writer(const fs::path& file_path, uint64_t block_stop);
bool initialize_file(uint64_t block_stop);
bool close();
void write_block(const crypto::hash &block_hash);

View File

@ -51,14 +51,14 @@ namespace
bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
bool BootstrapFile::open_writer(const fs::path& file_path)
{
const boost::filesystem::path dir_path = file_path.parent_path();
const auto dir_path = file_path.parent_path();
if (!dir_path.empty())
{
if (boost::filesystem::exists(dir_path))
if (fs::exists(dir_path))
{
if (!boost::filesystem::is_directory(dir_path))
if (!fs::is_directory(dir_path))
{
MFATAL("export directory path is a file: " << dir_path);
return false;
@ -66,7 +66,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
}
else
{
if (!boost::filesystem::create_directory(dir_path))
if (!fs::create_directory(dir_path))
{
MFATAL("Failed to create directory " << dir_path);
return false;
@ -79,7 +79,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path)
bool do_initialize_file = false;
uint64_t num_blocks = 0;
if (! boost::filesystem::exists(file_path))
if (! fs::exists(file_path))
{
MDEBUG("creating file");
do_initialize_file = true;
@ -264,7 +264,7 @@ bool BootstrapFile::close()
}
bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, fs::path& output_file, uint64_t requested_block_stop)
{
uint64_t num_blocks_written = 0;
m_max_chunk = 0;
@ -326,7 +326,7 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem
return BootstrapFile::close();
}
uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file)
uint64_t BootstrapFile::seek_to_first_chunk(fs::ifstream& import_file)
{
uint32_t file_magic;
@ -386,7 +386,7 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file)
return full_header_size;
}
uint64_t BootstrapFile::count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit)
uint64_t BootstrapFile::count_bytes(fs::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit)
{
uint64_t bytes_read = 0;
uint32_t chunk_size;
@ -445,7 +445,7 @@ uint64_t BootstrapFile::count_bytes(std::ifstream& import_file, uint64_t blocks,
return bytes_read;
}
uint64_t BootstrapFile::count_blocks(const std::string& import_file_path)
uint64_t BootstrapFile::count_blocks(const fs::path& import_file_path)
{
std::streampos dummy_pos;
uint64_t dummy_height = 0;
@ -455,17 +455,14 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path)
// If seek_height is non-zero on entry, return a stream position <= this height when finished.
// And return the actual height corresponding to this position. Allows the caller to locate its
// starting position without having to reread the entire file again.
uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, uint64_t& seek_height)
uint64_t BootstrapFile::count_blocks(const fs::path& import_file_path, std::streampos &start_pos, uint64_t& seek_height)
{
boost::filesystem::path raw_file_path(import_file_path);
boost::system::error_code ec;
if (!boost::filesystem::exists(raw_file_path, ec))
if (std::error_code ec; !fs::exists(import_file_path, ec))
{
MFATAL("bootstrap file not found: " << raw_file_path);
MFATAL("bootstrap file not found: " << import_file_path);
throw std::runtime_error("Aborting");
}
std::ifstream import_file;
import_file.open(import_file_path, std::ios_base::binary | std::ifstream::in);
fs::ifstream import_file{import_file_path, std::ios::binary};
uint64_t start_height = seek_height;
uint64_t h = 0;

View File

@ -32,8 +32,6 @@
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_core/blockchain.h"
@ -45,6 +43,7 @@
#include <atomic>
#include "common/command_line.h"
#include "common/fs.h"
#include "version.h"
#include "blockchain_utilities.h"
@ -57,13 +56,13 @@ class BootstrapFile
{
public:
uint64_t count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit);
uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height);
uint64_t count_blocks(const std::string& dir_path);
uint64_t seek_to_first_chunk(std::ifstream& import_file);
uint64_t count_bytes(fs::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit);
uint64_t count_blocks(const fs::path& dir_path, std::streampos& start_pos, uint64_t& seek_height);
uint64_t count_blocks(const fs::path& dir_path);
uint64_t seek_to_first_chunk(fs::ifstream& import_file);
bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0);
fs::path& output_file, uint64_t use_block_height=0);
protected:
@ -76,7 +75,7 @@ protected:
boost::iostreams::stream<boost::iostreams::back_insert_device<buffer_type>>* m_output_stream;
// open export file for write
bool open_writer(const boost::filesystem::path& file_path);
bool open_writer(const fs::path& file_path);
bool initialize_file();
bool close();
void write_block(block& block);

View File

@ -12,6 +12,7 @@ extern "C" {
#include <array>
#include <cstring>
#include <optional>
#include "common/fs.h"
std::string_view arg0;
@ -115,11 +116,8 @@ int generate(bool ed25519, std::list<std::string_view> args) {
if (pubkey_pos != std::string::npos)
overwrite = true;
if (!overwrite) {
std::ifstream f{filename};
if (f.good())
return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it");
}
if (!overwrite && fs::exists(fs::u8path(filename)))
return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it");
std::array<unsigned char, crypto_sign_PUBLICKEYBYTES> pubkey;
std::array<unsigned char, crypto_sign_SECRETKEYBYTES> seckey;
@ -140,7 +138,7 @@ int generate(bool ed25519, std::list<std::string_view> args) {
if (pubkey_pos != std::string::npos)
filename.replace(pubkey_pos, 6, lokimq::to_hex(pubkey.begin(), pubkey.end()));
std::ofstream out{filename, std::ios::trunc | std::ios::binary};
fs::ofstream out{fs::u8path(filename), std::ios::trunc | std::ios::binary};
if (!out.good())
return error(2, "Failed to open output file '" + filename + "': " + std::strerror(errno));
if (ed25519)
@ -191,10 +189,10 @@ int show(std::list<std::string_view> args) {
else if (args.size() > 1)
return error(2, "unknown arguments to 'show'");
std::string filename{args.front()};
std::ifstream in{filename, std::ios::binary};
fs::path filename = fs::u8path(args.front());
fs::ifstream in{filename, std::ios::binary};
if (!in.good())
return error(2, "Unable to open '" + filename + "': " + std::strerror(errno));
return error(2, "Unable to open '" + filename.u8string() + "': " + std::strerror(errno));
in.seekg(0, std::ios::end);
auto size = in.tellg();
@ -216,12 +214,12 @@ int show(std::list<std::string_view> args) {
std::array<unsigned char, crypto_sign_SECRETKEYBYTES> seckey;
in.read(reinterpret_cast<char*>(seckey.data()), size >= 64 ? 64 : 32);
if (!in.good())
return error(2, "Failed to read from " + filename + ": " + std::strerror(errno));
return error(2, "Failed to read from " + filename.u8string() + ": " + std::strerror(errno));
if (legacy) {
pubkey = pubkey_from_privkey(seckey);
std::cout << filename << " (legacy SN keypair)" << "\n==========" <<
std::cout << filename.u8string() << " (legacy SN keypair)" << "\n==========" <<
"\nPrivate key: " << lokimq::to_hex(seckey.begin(), seckey.begin() + 32) <<
"\nPublic key: " << lokimq::to_hex(pubkey.begin(), pubkey.end()) << "\n\n";
return 0;
@ -318,13 +316,11 @@ int restore(bool ed25519, std::list<std::string_view> args) {
if (pubkey_pos != std::string::npos)
filename.replace(pubkey_pos, 6, lokimq::to_hex(pubkey.begin(), pubkey.end()));
if (!overwrite) {
std::ifstream f{filename};
if (f.good())
return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it");
}
auto filepath = fs::u8path(filename);
if (!overwrite && fs::exists(filepath))
return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it");
std::ofstream out{filename, std::ios::trunc | std::ios::binary};
fs::ofstream out{filepath, std::ios::trunc | std::ios::binary};
if (!out.good())
return error(2, "Failed to open output file '" + filename + "': " + std::strerror(errno));
if (ed25519)

View File

@ -35,8 +35,7 @@ target_link_libraries(checkpoints
PRIVATE
common
cryptonote_basic
Boost::date_time
Boost::program_options
Boost::serialization
Boost::filesystem
filesystem
extra)

View File

@ -41,6 +41,7 @@
#include "common/loki_integration_test_hooks.h"
#include "common/loki.h"
#include "common/file.h"
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "checkpoints"
@ -88,17 +89,18 @@ namespace cryptonote
return result;
}
bool load_checkpoints_from_json(const std::string &json_hashfile_fullpath, std::vector<height_to_hash> &checkpoint_hashes)
bool load_checkpoints_from_json(const fs::path& json_hashfile_fullpath, std::vector<height_to_hash>& checkpoint_hashes)
{
boost::system::error_code errcode;
if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode)))
if (std::error_code ec; !fs::exists(json_hashfile_fullpath, ec))
{
LOG_PRINT_L1("Blockchain checkpoints file not found");
return true;
}
height_to_hash_json hashes;
if (!epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath))
if (std::string contents;
!tools::slurp_file(json_hashfile_fullpath, contents) ||
!epee::serialization::load_t_from_json(hashes, contents))
{
MERROR("Error loading checkpoints from " << json_hashfile_fullpath);
return false;

View File

@ -36,6 +36,7 @@
#include "cryptonote_config.h"
#include "cryptonote_core/service_node_voting.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "common/fs.h"
#define ADD_CHECKPOINT(h, hash) CHECK_AND_ASSERT(add_checkpoint(h, hash), false);
#define JSON_HASH_FILE_NAME "checkpoints.json"
@ -100,7 +101,7 @@ namespace cryptonote
};
crypto::hash get_newest_hardcoded_checkpoint(cryptonote::network_type nettype, uint64_t *height);
bool load_checkpoints_from_json (const std::string &json_hashfile_fullpath, std::vector<height_to_hash> &checkpoint_hashes);
bool load_checkpoints_from_json (const fs::path& json_hashfile_fullpath, std::vector<height_to_hash>& checkpoint_hashes);
/**
* @brief A container for blockchain checkpoints

View File

@ -73,6 +73,7 @@ target_link_libraries(common
PUBLIC
cncrypto
lokimq::lokimq
filesystem
PRIVATE
libunbound
OpenSSL::SSL

View File

@ -30,93 +30,58 @@
#pragma once
#include "misc_log_ex.h"
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/filesystem/operations.hpp>
#include "fs.h"
namespace tools
{
template<class t_object>
bool serialize_obj_to_file(t_object& obj, const std::string& file_path)
template <class T>
bool serialize_obj_to_file(T& obj, const fs::path& file_path)
{
TRY_ENTRY();
#if defined(_MSC_VER)
// Need to know HANDLE of file to call FlushFileBuffers
HANDLE data_file_handle = ::CreateFile(file_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == data_file_handle)
return false;
int data_file_descriptor = _open_osfhandle((intptr_t)data_file_handle, 0);
if (-1 == data_file_descriptor)
{
::CloseHandle(data_file_handle);
return false;
}
const std::unique_ptr<FILE, tools::close_file> data_file_file{_fdopen(data_file_descriptor, "wb")};
if (nullptr == data_file_file)
{
// Call CloseHandle is not necessary
_close(data_file_descriptor);
return false;
}
// HACK: undocumented constructor, this code may not compile
std::ofstream data_file(data_file_file.get());
if (data_file.fail())
{
// Call CloseHandle and _close are not necessary
return false;
}
#else
std::ofstream data_file;
data_file.open(file_path , std::ios_base::binary | std::ios_base::out| std::ios::trunc);
fs::ofstream data_file{file_path, std::ios::binary | std::ios::trunc};
if (data_file.fail())
return false;
#endif
boost::archive::portable_binary_oarchive a(data_file);
a << obj;
boost::archive::portable_binary_oarchive{data_file} << obj;
if (data_file.fail())
return false;
data_file.flush();
#if defined(_MSC_VER)
// To make sure the file is fully stored on disk
::FlushFileBuffers(data_file_handle);
#endif
return true;
CATCH_ENTRY_L0("serialize_obj_to_file", false);
}
template<class t_object>
bool unserialize_obj_from_file(t_object& obj, const std::string& file_path)
template <class T>
bool unserialize_obj_from_file(T& obj, const fs::path& file_path)
{
TRY_ENTRY();
std::ifstream data_file;
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
if(data_file.fail())
fs::ifstream data_file{file_path, std::ios_base::binary};
if (data_file.fail())
return false;
try
{
// first try reading in portable mode
boost::archive::portable_binary_iarchive a(data_file);
a >> obj;
boost::archive::portable_binary_iarchive{data_file} >> obj;
}
catch(...)
{
// if failed, try reading in unportable mode
boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
auto unportable = file_path;
unportable += ".unportable";
fs::copy_file(file_path, unportable, fs::copy_options::overwrite_existing);
data_file.close();
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
if(data_file.fail())
data_file.open(file_path, std::ios_base::binary);
if (data_file.fail())
return false;
boost::archive::binary_iarchive a(data_file);
a >> obj;
boost::archive::binary_iarchive{data_file} >> obj;
}
return !data_file.fail();
CATCH_ENTRY_L0("unserialize_obj_from_file", false);

View File

@ -38,7 +38,7 @@
#include <boost/program_options/parsers.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include "include_base_utils.h"
#include "misc_log_ex.h"
#include "common/string_util.h"
#include "common/i18n.h"

View File

@ -37,7 +37,7 @@
#include <stdexcept>
#include <cstdlib>
#include <cstdio>
#include "include_base_utils.h"
#include "misc_log_ex.h"
#include "common/threadpool.h"
#include "crypto/crypto.h"

View File

@ -47,7 +47,6 @@
#include <sys/utsname.h>
#include <sys/stat.h>
#endif
#include <boost/filesystem.hpp>
#ifdef __GLIBC__
#include <sys/types.h>
@ -85,10 +84,10 @@ namespace tools {
private_file::private_file() noexcept : m_handle(), m_filename() {}
private_file::private_file(std::FILE* handle, std::string&& filename) noexcept
private_file::private_file(std::FILE* handle, fs::path filename) noexcept
: m_handle(handle), m_filename(std::move(filename)) {}
private_file private_file::create(std::string name)
private_file private_file::create(fs::path name)
{
#ifdef WIN32
struct close_handle
@ -137,7 +136,7 @@ namespace tools {
SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false};
std::unique_ptr<void, close_handle> file{
CreateFile(
CreateFileW(
name.c_str(),
GENERIC_WRITE, FILE_SHARE_READ,
std::addressof(attributes),
@ -193,29 +192,15 @@ namespace tools {
private_file::~private_file() noexcept
{
try
{
boost::system::error_code ec{};
boost::filesystem::remove(filename(), ec);
}
catch (...) {}
std::error_code ignored;
fs::remove(filename(), ignored);
}
file_locker::file_locker(const std::string &filename)
file_locker::file_locker(const fs::path& filename)
{
#ifdef WIN32
m_fd = INVALID_HANDLE_VALUE;
std::wstring filename_wide;
try
{
filename_wide = epee::string_tools::utf8_to_utf16(filename);
}
catch (const std::exception &e)
{
MERROR("Failed to convert path \"" << filename << "\" to UTF-16: " << e.what());
return;
}
m_fd = CreateFileW(filename_wide.c_str(), GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
m_fd = CreateFileW(filename.c_str(), GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (m_fd != INVALID_HANDLE_VALUE)
{
OVERLAPPED ov;
@ -270,64 +255,43 @@ namespace tools {
#ifdef WIN32
std::string get_special_folder_path(int nfolder, bool iscreate)
fs::path get_special_folder_path(int nfolder, bool iscreate)
{
WCHAR psz_path[MAX_PATH] = L"";
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
{
try
{
return epee::string_tools::utf16_to_utf8(psz_path);
}
catch (const std::exception &e)
{
MERROR("utf16_to_utf8 failed: " << e.what());
return "";
}
return fs::path{psz_path};
}
LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path.");
return "";
}
#endif
std::string get_default_data_dir()
// Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME
fs::path get_default_data_dir()
{
/* Please for the love of god refactor the ifdefs out of this */
// namespace fs = boost::filesystem;
// Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME
// Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME
// Unix & Mac: ~/.CRYPTONOTE_NAME
std::string config_folder;
#ifdef WIN32
config_folder = get_special_folder_path(CSIDL_COMMON_APPDATA, true) + "\\" + CRYPTONOTE_NAME;
#else
std::string pathRet;
char* pszHome = getenv("HOME");
if (pszHome == NULL || strlen(pszHome) == 0)
pathRet = "/";
else
pathRet = pszHome;
config_folder = (pathRet + "/." + CRYPTONOTE_NAME);
#endif
return config_folder;
return get_special_folder_path(CSIDL_COMMON_APPDATA, true) / fs::u8path(CRYPTONOTE_NAME);
}
bool create_directories_if_necessary(const std::string& path)
#else
// Non-windows: ~/.CRYPTONOTE_NAME
fs::path get_default_data_dir()
{
namespace fs = boost::filesystem;
boost::system::error_code ec;
fs::path fs_path(path);
if (fs::is_directory(fs_path, ec))
std::string_view home{getenv("HOME")};
return fs::u8path(!home.empty() ? home : "/"sv) / fs::u8path("." CRYPTONOTE_NAME);
}
#endif
bool create_directories_if_necessary(const fs::path& path)
{
std::error_code ec;
if (fs::is_directory(path, ec))
{
return true;
}
bool res = fs::create_directories(fs_path, ec);
bool res = fs::create_directories(path, ec);
if (res)
{
LOG_PRINT_L2("Created directory: " << path);
@ -340,33 +304,6 @@ namespace tools {
return res;
}
std::error_code replace_file(const std::string& old_name, const std::string& new_name)
{
int code;
#if defined(WIN32)
// Maximizing chances for success
std::wstring wide_replacement_name;
try { wide_replacement_name = epee::string_tools::utf8_to_utf16(old_name); }
catch (...) { return std::error_code(GetLastError(), std::system_category()); }
std::wstring wide_replaced_name;
try { wide_replaced_name = epee::string_tools::utf8_to_utf16(new_name); }
catch (...) { return std::error_code(GetLastError(), std::system_category()); }
DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str());
if (INVALID_FILE_ATTRIBUTES != attributes)
{
::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY));
}
bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING);
code = ok ? 0 : static_cast<int>(::GetLastError());
#else
bool ok = 0 == std::rename(old_name.c_str(), new_name.c_str());
code = ok ? 0 : errno;
#endif
return std::error_code(code, std::system_category());
}
void set_strict_default_file_permissions(bool strict)
{
#if defined(__MINGW32__) || defined(__MINGW__)
@ -377,4 +314,36 @@ namespace tools {
#endif
}
bool slurp_file(const fs::path& filename, std::string& contents)
{
fs::ifstream in;
in.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
in.open(filename, std::ios::binary | std::ios::in | std::ios::ate);
contents.clear();
contents.resize(in.tellg());
in.seekg(0);
in.read(contents.data(), contents.size());
auto bytes_read = in.gcount();
if (static_cast<size_t>(bytes_read) < contents.size())
contents.resize(bytes_read);
return true;
} catch (...) {
return false;
}
}
bool dump_file(const fs::path& filename, std::string_view contents)
{
fs::ofstream out;
out.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
out.open(filename, std::ios::binary | std::ios::out | std::ios::trunc);
out.write(contents.data(), contents.size());
return true;
} catch (...) {
return false;
}
}
}

View File

@ -36,6 +36,7 @@
#include <memory>
#include <optional>
#include <system_error>
#include "fs.h"
#ifdef _WIN32
#include "windows.h"
@ -63,9 +64,9 @@ namespace tools {
//! A file restricted to process owner AND process. Deletes file on destruction.
class private_file {
std::unique_ptr<std::FILE, close_file> m_handle;
std::string m_filename;
fs::path m_filename;
private_file(std::FILE* handle, std::string&& filename) noexcept;
private_file(std::FILE* handle, fs::path filename) noexcept;
public:
//! `handle() == nullptr && filename.empty()`.
@ -73,7 +74,7 @@ namespace tools {
/*! \return File only readable by owner and only used by this process
OR `private_file{}` on error. */
static private_file create(std::string filename);
static private_file create(fs::path filename);
private_file(private_file&&) = default;
private_file& operator=(private_file&&) = default;
@ -82,13 +83,13 @@ namespace tools {
~private_file() noexcept;
std::FILE* handle() const noexcept { return m_handle.get(); }
const std::string& filename() const noexcept { return m_filename; }
const fs::path& filename() const noexcept { return m_filename; }
};
class file_locker
{
public:
file_locker(const std::string &filename);
file_locker(const fs::path& filename);
~file_locker();
bool locked() const;
private:
@ -109,7 +110,7 @@ namespace tools {
*
* Unix: ~/.CRYPTONOTE_NAME
*/
std::string get_default_data_dir();
fs::path get_default_data_dir();
#ifdef WIN32
/**
@ -120,21 +121,24 @@ namespace tools {
*
* @return
*/
std::string get_special_folder_path(int nfolder, bool iscreate);
fs::path get_special_folder_path(int nfolder, bool iscreate);
#endif
/*! \brief creates directories for a path
*
* wrapper around boost::filesyste::create_directories.
* (ensure-directory-exists): greenspun's tenth rule in action!
* wrapper around fs::create_directories.
*/
bool create_directories_if_necessary(const std::string& path);
/*! \brief std::rename wrapper for nix and something strange for windows.
*/
std::error_code replace_file(const std::string& old_name, const std::string& new_name);
bool create_directories_if_necessary(const fs::path& path);
void set_strict_default_file_permissions(bool strict);
void closefrom(int fd);
/// Reads a (binary) file from disk into the string `contents`. Aborts if the file is larger than
/// `max_size`.
bool slurp_file(const fs::path& filename, std::string& contents);
/// Dumps (binary) string contents to disk. The file is overwritten if it already exists.
bool dump_file(const fs::path& filename, std::string_view contents);
}

25
src/common/fs.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
// Header to load the std::filesystem namespace (or something compatible with it) as the `fs`
// namespace. For older compilers (which generally just means macos before pre-10.15) we can't
// actually use std::filesystem because Apple's libc++ developers are incompetent.
//
// Also provides fs::ifstream/ofstream/fstream which will be either directly
// std::ifstream/ofstream/fstream (if under a proper C++17), or a simple wrapper around them that
// supports a C++17-style fs::path filename argument.
#ifndef USE_GHC_FILESYSTEM
#include <filesystem>
namespace fs {
using namespace std::filesystem;
using ifstream = std::ifstream;
using ofstream = std::ofstream;
using fstream = std::fstream;
}
#else
#include <ghc/filesystem.hpp>
namespace fs = ghc::filesystem;
#endif

View File

@ -35,7 +35,8 @@
#include <string>
#include <map>
#include <utility>
#include "file_io_utils.h"
#include <algorithm>
#include "file.h"
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "i18n"
@ -134,51 +135,40 @@ static std::string utf8(const unsigned char *data, uint32_t len)
int i18n_set_language(const char *directory, const char *base, std::string language)
{
std::string filename, contents;
const unsigned char *data;
size_t datalen;
size_t idx;
unsigned char chunk_type;
uint32_t chunk_size;
uint32_t num_messages = (uint32_t)-1;
uint32_t messages_idx = (uint32_t)-1;
uint32_t offsets_idx = (uint32_t)-1;
std::string translation, source, context;
i18n_log("i18n_set_language(" << directory << "," << base << ")");
if (!directory || !base)
return -1;
if (language.empty())
language = i18n_get_language();
filename = std::string(directory) + "/" + base + "_" + language + ".qm";
std::string basename = base + "_"s + language + ".qm";
auto filename = fs::u8path(directory) / fs::u8path(basename);
i18n_log("Loading translations for language " << language);
boost::system::error_code ignored_ec;
if (boost::filesystem::exists(filename, ignored_ec)) {
if (!epee::file_io_utils::load_file_to_string(filename, contents)) {
std::string contents;
if (std::error_code ec; fs::exists(filename, ec)) {
if (!tools::slurp_file(filename, contents)) {
i18n_log("Failed to load translations file: " << filename);
return -1;
}
} else {
i18n_log("Translations file not found: " << filename);
filename = std::string(base) + "_" + language + ".qm";
if (!find_embedded_file(filename, contents)) {
i18n_log("Embedded translations file not found: " << filename);
if (!find_embedded_file(basename, contents)) {
i18n_log("Embedded translations file not found: " << basename);
const char *underscore = strchr(language.c_str(), '_');
if (underscore) {
std::string fallback_language = std::string(language, 0, underscore - language.c_str());
filename = std::string(directory) + "/" + base + "_" + fallback_language + ".qm";
basename = base + "_"s + fallback_language + ".qm";
filename.replace_filename(fs::u8path(basename));
i18n_log("Loading translations for language " << fallback_language);
if (boost::filesystem::exists(filename, ignored_ec)) {
if (!epee::file_io_utils::load_file_to_string(filename, contents)) {
if (std::error_code ec; fs::exists(filename, ec)) {
if (!tools::slurp_file(filename, contents)) {
i18n_log("Failed to load translations file: " << filename);
return -1;
}
} else {
i18n_log("Translations file not found: " << filename);
filename = std::string(base) + "_" + fallback_language + ".qm";
if (!find_embedded_file(filename, contents)) {
if (!find_embedded_file(basename, contents)) {
i18n_log("Embedded translations file not found: " << filename);
return -1;
}
@ -189,9 +179,9 @@ int i18n_set_language(const char *directory, const char *base, std::string langu
}
}
data = (const unsigned char*)contents.c_str();
datalen = contents.size();
idx = 0;
const unsigned char *data = reinterpret_cast<const unsigned char*>(contents.c_str());
size_t datalen = contents.size();
size_t idx = 0;
i18n_log("Translations file size: " << datalen);
/* Format of the QM file (AFAICT):
@ -225,6 +215,11 @@ int i18n_set_language(const char *directory, const char *base, std::string langu
}
idx += sizeof(qm_magic);
unsigned char chunk_type;
uint32_t chunk_size;
uint32_t num_messages = (uint32_t)-1;
uint32_t messages_idx = (uint32_t)-1;
uint32_t offsets_idx = (uint32_t)-1;
while (idx < datalen) {
if (idx + 5 > datalen) {
i18n_log("Bad translations file format: " << filename);
@ -268,6 +263,7 @@ int i18n_set_language(const char *directory, const char *base, std::string langu
return -1;
}
std::string translation, source, context;
for (uint32_t m = 0; m < num_messages; ++m) {
be32(data+offsets_idx+m*8); // unused
idx = be32(data+offsets_idx+m*8+4);
@ -287,9 +283,9 @@ int i18n_set_language(const char *directory, const char *base, std::string langu
chunk_size = 0;
if (chunk_type == 0x01) {
i18n_entries[context + "\0"s + source] = translation;
context = std::string();
source = std::string();
translation = std::string();
context.clear();
source.clear();
translation.clear();
break;
}

View File

@ -29,7 +29,6 @@
#include <boost/algorithm/string.hpp>
#include <stdarg.h>
#include "misc_log_ex.h"
#include "file_io_utils.h"
#include "spawn.h"
#include "notify.h"
@ -52,8 +51,8 @@ Notify::Notify(const char *spec)
CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec");
if (strchr(spec, '\'') || strchr(spec, '\"') || strchr(spec, '\\'))
MWARNING("A notification spec contains a quote or backslash: note that these are handled verbatim, which may not be the intent");
filename = args[0];
CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename);
filename = fs::u8path(args[0]);
CHECK_AND_ASSERT_THROW_MES(fs::exists(filename), "File not found: " << filename);
}
static void replace(std::vector<std::string> &v, const char *tag, const char *s)
@ -77,7 +76,7 @@ int Notify::notify(const char *tag, const char *s, ...)
}
va_end(ap);
return tools::spawn(filename.c_str(), margs, false);
return tools::spawn(filename, margs, false);
}
}

View File

@ -30,6 +30,7 @@
#include <string>
#include <vector>
#include "fs.h"
namespace tools
{
@ -42,7 +43,7 @@ public:
int notify(const char *tag, const char *s, ...);
private:
std::string filename;
fs::path filename;
std::vector<std::string> args;
};

View File

@ -2,7 +2,7 @@
#include "sha256sum.h"
#include <fstream>
#include "crypto/hash.h"
#include "file_io_utils.h" // epee
#include "fs.h"
extern "C" {
#include <openssl/sha.h>
@ -22,11 +22,11 @@ namespace tools {
return true;
}
bool sha256sum_file(const std::string &filename, crypto::hash &hash)
bool sha256sum_file(const fs::path& filename, crypto::hash& hash)
{
if (!epee::file_io_utils::is_file_exist(filename))
if (std::error_code ec; !fs::exists(filename, ec) || ec)
return false;
std::ifstream f;
fs::ifstream f;
f.exceptions(std::ifstream::failbit | std::ifstream::badbit);
f.open(filename, std::ios_base::binary | std::ios_base::in | std::ios::ate);
if (!f)

View File

@ -2,14 +2,15 @@
#include <type_traits>
#include <string>
#include <string_view>
#include "fs.h"
namespace crypto { struct hash; }
namespace tools {
// This used to be really dangerously overloaded with very different purposes:
//bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash);
//bool sha256sum(const std::string &filename, crypto::hash &hash);
//bool sha256sum(const uint8_t* data, size_t len, crypto::hash& hash);
//bool sha256sum(const fs::path& filename, crypto::hash& hash);
// which is incredibly dangerous if you happen to have a string you want to hash and see that
// there is both a pointer+size and std::string overload. Renamed *both* of these to prevent any
// existing code from compiling.
@ -34,6 +35,6 @@ namespace tools {
}
// Opens the given file and calculates a sha256sum of its contents
bool sha256sum_file(const std::string &filename, crypto::hash& hash);
bool sha256sum_file(const fs::path& filename, crypto::hash& hash);
}

View File

@ -70,7 +70,7 @@ static void closefrom(int fd)
#endif
int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
int spawn(const fs::path& filename, const std::vector<std::string>& args, bool wait)
{
#ifdef _WIN32
std::string joined = tools::join(" ", args);
@ -78,12 +78,15 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
STARTUPINFOA si = {};
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
if (!CreateProcessA(filename, commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi))
// This .string() is wrong for non-ascii paths, but if we switch to CreateProcessW and use
// .c_str() directly our commandLine argument will not be accepted (because it then has to be a
// wchar_t* but out input is utf-8). Shame on you for this garbage API, Windows.
if (!CreateProcessA(filename.string().c_str(), commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi))
{
MERROR("CreateProcess failed. Error code " << GetLastError());
return -1;
}
LOKI_DEFER {
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
@ -129,7 +132,7 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
tools::closefrom(3);
close(0);
char *envp[] = {NULL};
execve(filename, argv.data(), envp);
execve(filename.c_str(), argv.data(), envp);
MERROR("Failed to execve: " << strerror(errno));
return -1;
}

View File

@ -29,10 +29,11 @@
#pragma once
#include <vector>
#include <string>
#include "common/fs.h"
namespace tools
{
int spawn(const char *filename, const std::vector<std::string>& args, bool wait);
int spawn(const fs::path& filename, const std::vector<std::string>& args, bool wait);
}

View File

@ -37,7 +37,6 @@
#include "unbound.h"
#include "include_base_utils.h"
#include "string_tools.h"
#include "wipeable_string.h"
#include "crypto/crypto.h"
@ -46,7 +45,6 @@
#include "misc_os_dependent.h"
#include "readline_buffer.h"
#include "string_util.h"
#include <boost/filesystem/path.hpp>
#include "i18n.h"
@ -76,29 +74,6 @@ namespace tools
return with_threads;
}
bool sanitize_locale()
{
// boost::filesystem throws for "invalid" locales, such as en_US.UTF-8, or kjsdkfs,
// so reset it here before any calls to it
try
{
boost::filesystem::path p {std::string("test")};
p /= std::string("test");
}
catch (...)
{
#if defined(__MINGW32__) || defined(__MINGW__)
putenv("LC_ALL=C");
putenv("LANG=C");
#else
setenv("LC_ALL", "C", 1);
setenv("LANG", "C", 1);
#endif
return true;
}
return false;
}
#ifdef STACK_TRACE
#ifdef _WIN32
// https://stackoverflow.com/questions/1992816/how-to-handle-seg-faults-under-windows
@ -170,8 +145,6 @@ namespace tools
setup_crash_dump();
sanitize_locale();
#ifdef __GLIBC__
const char *ver = ::gnu_get_libc_version();
if (!strcmp(ver, "2.25"))

View File

@ -47,8 +47,6 @@
*/
namespace tools
{
bool sanitize_locale();
bool disable_core_dumps();
bool on_startup();

View File

@ -57,7 +57,6 @@ target_link_libraries(cncrypto
PUBLIC
epee
randomx
Boost::system
Boost::thread
sodium
PRIVATE

View File

@ -39,8 +39,7 @@ target_link_libraries(cryptonote_basic
PRIVATE
common
device
Boost::date_time
Boost::program_options
Boost::serialization
Boost::filesystem
filesystem
extra)

View File

@ -31,7 +31,6 @@
#include <fstream>
#include "include_base_utils.h"
#include "account.h"
#include "warnings.h"
#include "crypto/crypto.h"

View File

@ -94,9 +94,6 @@ namespace cryptonote
uint64_t get_createtime() const { return m_creation_timestamp; }
void set_createtime(uint64_t val) { m_creation_timestamp = val; }
bool load(const std::string& file_path);
bool store(const std::string& file_path);
void forget_spend_key();
const std::vector<crypto::secret_key> &get_multisig_keys() const { return m_keys.m_multisig_keys; }

View File

@ -29,8 +29,6 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "include_base_utils.h"
#include "cryptonote_basic_impl.h"
#include "string_tools.h"
#include "serialization/binary_utils.h"

View File

@ -34,7 +34,6 @@
#include "tx_extra.h"
#include "account.h"
#include "subaddress_index.h"
#include "include_base_utils.h"
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "common/meta.h"

View File

@ -31,13 +31,13 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include <numeric>
#include "lokimq/base64.h"
#include <lokimq/base64.h>
#include "misc_language.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "misc_os_dependent.h"
#include "file_io_utils.h"
#include "common/command_line.h"
#include "common/util.h"
#include "common/file.h"
#include "common/string_util.h"
#include "string_coding.h"
#include "string_tools.h"
@ -245,7 +245,7 @@ namespace cryptonote
if(command_line::has_arg(vm, arg_extra_messages))
{
std::string buff;
bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, arg_extra_messages), buff);
bool r = tools::slurp_file(fs::u8path(command_line::get_arg(vm, arg_extra_messages)), buff);
CHECK_AND_ASSERT_MES(r, false, "Failed to load file with extra messages: " << command_line::get_arg(vm, arg_extra_messages));
auto extra_vec = tools::split_any(buff, "\n"sv, true);
m_extra_messages.resize(extra_vec.size());
@ -264,10 +264,16 @@ namespace cryptonote
if(buff != "0")
m_extra_messages[i] = buff;
}
m_config_folder_path = boost::filesystem::path(command_line::get_arg(vm, arg_extra_messages)).parent_path().string();
m_config_dir = fs::u8path(command_line::get_arg(vm, arg_extra_messages)).parent_path();
m_config = {};
const std::string filename = m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME;
CHECK_AND_ASSERT_MES(epee::serialization::load_t_from_json_file(m_config, filename), false, "Failed to load data from " << filename);
fs::path filename = m_config_dir / MINER_CONFIG_FILE_NAME;
if (std::string contents;
!tools::slurp_file(filename, contents) ||
!epee::serialization::load_t_from_json(m_config, contents))
{
MERROR("Failed to load data from " << filename);
return false;
}
MINFO("Loaded " << m_extra_messages.size() << " extra messages, current index " << m_config.current_extra_message_index);
}
@ -493,14 +499,11 @@ namespace cryptonote
MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff);
cryptonote::block_verification_context bvc;
if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain)
{
--m_config.current_extra_message_index;
}else
{
else if (!m_config_dir.empty())
//success update, lets update config
if (!m_config_folder_path.empty())
epee::serialization::store_t_to_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME);
}
if (std::string json; epee::serialization::store_t_to_json(m_config, json))
tools::dump_file(m_config_dir / fs::u8path(MINER_CONFIG_FILE_NAME), json);
}
nonce+=m_threads_total;

View File

@ -37,6 +37,7 @@
#include "cryptonote_basic/verification_context.h"
#include "cryptonote_basic/difficulty.h"
#include "common/periodic_task.h"
#include "common/fs.h"
#ifdef _WIN32
#include <windows.h>
#endif
@ -123,7 +124,7 @@ namespace cryptonote
tools::periodic_task m_autodetect_interval{1s};
std::vector<blobdata> m_extra_messages;
miner_config m_config;
std::string m_config_folder_path;
fs::path m_config_dir;
std::atomic<uint64_t> m_last_hr_merge_time;
std::atomic<uint64_t> m_hashes;
std::atomic<uint64_t> m_total_hashes;

View File

@ -31,12 +31,10 @@
#include <algorithm>
#include <cstdio>
#include <boost/filesystem.hpp>
#include <boost/endian/conversion.hpp>
#include "common/rules.h"
#include "common/hex.h"
#include "include_base_utils.h"
#include "cryptonote_basic/cryptonote_basic_impl.h"
#include "cryptonote_core/cryptonote_tx_utils.h"
#include "ringct/rctTypes.h"
@ -48,7 +46,6 @@
#include "cryptonote_basic/miner.h"
#include "misc_language.h"
#include "profile_tools.h"
#include "file_io_utils.h"
#include "int-util.h"
#include "common/threadpool.h"
#include "common/boost_serialization_helper.h"
@ -3206,7 +3203,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
}
else
{
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + std::to_string(rv.type));
}
// II
@ -3239,7 +3236,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
}
else
{
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + std::to_string(rv.type));
}
// outPk was already done by handle_incoming_tx
@ -4696,7 +4693,7 @@ bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc,
// returns false if any of the checkpoints loading returns false.
// That should happen only if a checkpoint is added that conflicts
// with an existing checkpoint.
bool Blockchain::update_checkpoints_from_json_file(const std::string& file_path)
bool Blockchain::update_checkpoints_from_json_file(const fs::path& file_path)
{
std::vector<height_to_hash> checkpoint_hashes;
if (!cryptonote::load_checkpoints_from_json(file_path, checkpoint_hashes))

View File

@ -769,7 +769,7 @@ namespace cryptonote
*
* @return false if any enforced checkpoint type fails to load, otherwise true
*/
bool update_checkpoints_from_json_file(const std::string& file_path);
bool update_checkpoints_from_json_file(const fs::path& file_path);
bool update_checkpoint(checkpoint_t const &checkpoint);

View File

@ -57,7 +57,6 @@ extern "C" {
#include "crypto/crypto.h"
#include "cryptonote_config.h"
#include "misc_language.h"
#include "file_io_utils.h"
#include <csignal>
#include "checkpoints/checkpoints.h"
#include "ringct/rctTypes.h"
@ -118,13 +117,13 @@ namespace cryptonote
const command_line::arg_descriptor<std::string, false, true, 2> arg_data_dir = {
"data-dir"
, "Specify data directory"
, tools::get_default_data_dir()
, tools::get_default_data_dir().u8string()
, {{ &arg_testnet_on, &arg_devnet_on }}
, [](std::array<bool, 2> testnet_devnet, bool defaulted, std::string val)->std::string {
if (testnet_devnet[0])
return (boost::filesystem::path(val) / "testnet").string();
return (fs::u8path(val) / "testnet").u8string();
else if (testnet_devnet[1])
return (boost::filesystem::path(val) / "devnet").string();
return (fs::u8path(val) / "devnet").u8string();
return val;
}
};
@ -279,7 +278,6 @@ namespace cryptonote
, m_pprotocol(&m_protocol_stub)
, m_starter_message_showed(false)
, m_target_blockchain_height(0)
, m_checkpoints_path("")
, m_last_json_checkpoints_update(0)
, m_nettype(UNDEFINED)
, m_last_storage_server_ping(0)
@ -377,7 +375,7 @@ namespace cryptonote
m_nettype = testnet ? TESTNET : devnet ? DEVNET : MAINNET;
}
m_config_folder = command_line::get_arg(vm, arg_data_dir);
m_config_folder = fs::u8path(command_line::get_arg(vm, arg_data_dir));
test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height));
m_pad_transactions = get_arg(vm, arg_pad_transactions);
@ -616,16 +614,20 @@ namespace cryptonote
m_service_node_list.set_my_service_node_keys(&m_service_keys);
}
boost::filesystem::path folder(m_config_folder);
auto folder = m_config_folder;
if (m_nettype == FAKECHAIN)
folder /= "fake";
// make sure the data directory exists, and try to lock it
CHECK_AND_ASSERT_MES (boost::filesystem::exists(folder) || boost::filesystem::create_directories(folder), false,
std::string("Failed to create directory ").append(folder.string()).c_str());
if (std::error_code ec; !fs::create_directories(folder, ec) && ec)
{
MERROR("Failed to create directory " + folder.u8string() + (ec ? ": " + ec.message() : ""s));
return false;
}
std::unique_ptr<BlockchainDB> db(new_db());
if (db == NULL)
if (!db)
{
LOG_ERROR("Failed to initialize a database");
return false;
@ -634,9 +636,8 @@ namespace cryptonote
auto lns_db_file_path = folder / "lns.db";
folder /= db->get_db_name();
MGINFO("Loading blockchain from folder " << folder.string() << " ...");
MGINFO("Loading blockchain from folder " << folder << " ...");
const std::string filename = folder.string();
// default to fast:async:1 if overridden
blockchain_db_sync_mode sync_mode = db_defaultsync;
bool sync_on_blocks = true;
@ -646,12 +647,12 @@ namespace cryptonote
if (m_nettype == FAKECHAIN && !keep_fakechain)
{
// reset the db by removing the database file before opening it
if (!db->remove_data_file(filename))
if (!db->remove_data_file(folder))
{
MERROR("Failed to remove data file in " << filename);
MERROR("Failed to remove data file in " << folder);
return false;
}
boost::filesystem::remove(lns_db_file_path);
fs::remove(lns_db_file_path);
}
#endif
@ -732,7 +733,7 @@ namespace cryptonote
if (db_salvage)
db_flags |= DBF_SALVAGE;
db->open(filename, m_nettype, db_flags);
db->open(folder, m_nettype, db_flags);
if(!db->m_open)
return false;
}
@ -800,14 +801,9 @@ namespace cryptonote
}
// Checkpoints
{
auto data_dir = boost::filesystem::path(m_config_folder);
boost::filesystem::path json(JSON_HASH_FILE_NAME);
boost::filesystem::path checkpoint_json_hashfile_fullpath = data_dir / json;
m_checkpoints_path = checkpoint_json_hashfile_fullpath.string();
}
m_checkpoints_path = m_config_folder / fs::u8path(JSON_HASH_FILE_NAME);
sqlite3 *lns_db = lns::init_loki_name_system(lns_db_file_path.string().c_str(), db->is_read_only());
sqlite3 *lns_db = lns::init_loki_name_system(lns_db_file_path, db->is_read_only());
if (!lns_db) return false;
init_lokimq(vm);
@ -863,16 +859,17 @@ namespace cryptonote
/// returns true for success/false for failure
/// generate_pair - a void function taking (privkey &, pubkey &) that sets them to the generated values; can throw on error.
template <typename Privkey, typename Pubkey, typename GetPubkey, typename GeneratePair>
bool init_key(const std::string &keypath, Privkey &privkey, Pubkey &pubkey, GetPubkey get_pubkey, GeneratePair generate_pair) {
if (epee::file_io_utils::is_file_exist(keypath))
bool init_key(const fs::path &keypath, Privkey &privkey, Pubkey &pubkey, GetPubkey get_pubkey, GeneratePair generate_pair) {
std::error_code ec;
if (fs::exists(keypath, ec))
{
std::string keystr;
bool r = epee::file_io_utils::load_file_to_string(keypath, keystr);
bool r = tools::slurp_file(keypath, keystr);
memcpy(&unwrap(unwrap(privkey)), keystr.data(), sizeof(privkey));
memwipe(&keystr[0], keystr.size());
CHECK_AND_ASSERT_MES(r, false, "failed to load service node key from " + keypath);
CHECK_AND_ASSERT_MES(r, false, "failed to load service node key from " + keypath.u8string());
CHECK_AND_ASSERT_MES(keystr.size() == sizeof(privkey), false,
"service node key file " + keypath + " has an invalid size");
"service node key file " + keypath.u8string() + " has an invalid size");
r = get_pubkey(privkey, pubkey);
CHECK_AND_ASSERT_MES(r, false, "failed to generate pubkey from secret key");
@ -886,13 +883,10 @@ namespace cryptonote
return false;
}
std::string keystr(reinterpret_cast<const char *>(&privkey), sizeof(privkey));
bool r = epee::file_io_utils::save_string_to_file(keypath, keystr);
memwipe(&keystr[0], keystr.size());
CHECK_AND_ASSERT_MES(r, false, "failed to save service node key to " + keypath);
bool r = tools::dump_file(keypath, tools::view_guts(privkey));
CHECK_AND_ASSERT_MES(r, false, "failed to save service node key to " + keypath.u8string());
using namespace boost::filesystem;
permissions(keypath, owner_read);
fs::permissions(keypath, fs::perms::owner_read, ec);
}
return true;
}
@ -919,7 +913,7 @@ namespace cryptonote
// only contains the private key value but not the secret key value that we need for full
// Ed25519 signing).
//
if (!init_key(m_config_folder + "/key_ed25519", keys.key_ed25519, keys.pub_ed25519,
if (!init_key(m_config_folder / "key_ed25519", keys.key_ed25519, keys.pub_ed25519,
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_sk_to_pk(pk.data, sk.data); return true; },
[](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_keypair(pk.data, sk.data); })
)
@ -936,7 +930,7 @@ namespace cryptonote
// *just* the private point, but not the seed, and so cannot be used for full Ed25519 signatures
// (which rely on the seed for signing).
if (m_service_node) {
if (!epee::file_io_utils::is_file_exist(m_config_folder + "/key")) {
if (std::error_code ec; !fs::exists(m_config_folder / "key", ec)) {
epee::wipeable_string privkey_signhash;
privkey_signhash.resize(crypto_hash_sha512_BYTES);
unsigned char* pk_sh_data = reinterpret_cast<unsigned char*>(privkey_signhash.data());
@ -952,7 +946,7 @@ namespace cryptonote
if (!crypto::secret_key_to_public_key(keys.key, keys.pub))
throw std::runtime_error{"Failed to derive primary key from ed25519 key"};
assert(0 == std::memcmp(keys.pub.data, keys.pub_ed25519.data, 32));
} else if (!init_key(m_config_folder + "/key", keys.key, keys.pub,
} else if (!init_key(m_config_folder / "key", keys.key, keys.pub,
crypto::secret_key_to_public_key,
[](crypto::secret_key &key, crypto::public_key &pubkey) {
throw std::runtime_error{"Internal error: old-style public keys are no longer generated"};
@ -2491,9 +2485,7 @@ namespace cryptonote
//-----------------------------------------------------------------------------------------------
uint64_t core::get_free_space() const
{
boost::filesystem::path path(m_config_folder);
boost::filesystem::space_info si = boost::filesystem::space(path);
return si.available;
return fs::space(m_config_folder).available;
}
//-----------------------------------------------------------------------------------------------
std::shared_ptr<const service_nodes::quorum> core::get_quorum(service_nodes::quorum_type type, uint64_t height, bool include_old, std::vector<std::shared_ptr<const service_nodes::quorum>> *alt_states) const

View File

@ -1020,7 +1020,7 @@ namespace cryptonote
/**
* @brief returns the lokid config directory
*/
const std::string& get_config_directory() const { return m_config_folder; }
const fs::path& get_config_directory() const { return m_config_folder; }
private:
@ -1188,7 +1188,7 @@ namespace cryptonote
//m_miner and m_miner_addres are probably temporary here
miner m_miner; //!< miner instance
std::string m_config_folder; //!< folder to look in for configs and other files
fs::path m_config_folder; //!< folder to look in for configs and other files
tools::periodic_task m_store_blockchain_interval{12h, false}; //!< interval for manual storing of Blockchain, if enabled
@ -1208,7 +1208,7 @@ namespace cryptonote
network_type m_nettype; //!< which network are we on?
std::string m_checkpoints_path; //!< path to json checkpoints file
fs::path m_checkpoints_path; //!< path to json checkpoints file
time_t m_last_json_checkpoints_update; //!< time when json checkpoints were last updated
std::atomic_flag m_checkpoints_updating; //!< set if checkpoints are currently updating to avoid multiple threads attempting to update at once

View File

@ -30,7 +30,6 @@
#include <unordered_set>
#include <random>
#include "include_base_utils.h"
#include "string_tools.h"
#include "common/apply_permutation.h"
#include "common/hex.h"

View File

@ -555,7 +555,7 @@ sql_compiled_statement::~sql_compiled_statement()
sqlite3_finalize(statement);
}
sqlite3 *init_loki_name_system(char const *file_path, bool read_only)
sqlite3 *init_loki_name_system(const fs::path& file_path, bool read_only)
{
sqlite3 *result = nullptr;
int sql_init = sqlite3_initialize();
@ -566,7 +566,7 @@ sqlite3 *init_loki_name_system(char const *file_path, bool read_only)
}
int const flags = read_only ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
int sql_open = sqlite3_open_v2(file_path, &result, flags, nullptr);
int sql_open = sqlite3_open_v2(file_path.u8string().c_str(), &result, flags, nullptr);
if (sql_open != SQLITE_OK)
{
MERROR("Failed to open LNS db at: " << file_path << ", reason: " << sqlite3_errstr(sql_open));

View File

@ -5,6 +5,7 @@
#include "cryptonote_config.h"
#include "span.h"
#include "cryptonote_basic/tx_extra.h"
#include "common/fs.h"
#include <lokimq/hex.h>
#include <cassert>
@ -130,7 +131,7 @@ constexpr bool mapping_type_allowed(uint8_t hf_version, mapping_type type) {
// relevant within a LNS buy tx).
std::vector<mapping_type> all_mapping_types(uint8_t hf_version);
sqlite3 *init_loki_name_system(char const *file_path, bool read_only);
sqlite3 *init_loki_name_system(const fs::path& file_path, bool read_only);
/// Returns the integer value used in the database and in RPC lookup calls for the given mapping
/// type. In particularly this maps all mapping_type::lokinet_Xyears values to the underlying value

View File

@ -30,7 +30,6 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include <algorithm>
#include <boost/filesystem.hpp>
#include <unordered_set>
#include <vector>

View File

@ -29,7 +29,6 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
#include "include_base_utils.h"
#include <set>
#include <unordered_map>

View File

@ -46,8 +46,7 @@ target_link_libraries(daemon
serialization
daemon_rpc_server
version
Boost::filesystem
filesystem
Boost::program_options
Boost::system
systemd
extra)

View File

@ -44,11 +44,9 @@ namespace daemon_args
, {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }}
, [](std::array<bool, 2> testnet_devnet, bool defaulted, std::string val)->std::string {
if (testnet_devnet[0] && defaulted)
return (daemonizer::get_default_data_dir() / "testnet" /
std::string(CRYPTONOTE_NAME ".conf")).string();
return (daemonizer::get_default_data_dir() / "testnet" / (CRYPTONOTE_NAME ".conf")).u8string();
else if (testnet_devnet[1] && defaulted)
return (daemonizer::get_default_data_dir() / "devnet" /
std::string(CRYPTONOTE_NAME ".conf")).string();
return (daemonizer::get_default_data_dir() / "devnet" / (CRYPTONOTE_NAME ".conf")).u8string();
return val;
}
};
@ -59,11 +57,9 @@ namespace daemon_args
, {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }}
, [](std::array<bool, 2> testnet_devnet, bool defaulted, std::string val)->std::string {
if (testnet_devnet[0] && defaulted)
return (daemonizer::get_default_data_dir() / "testnet" /
std::string(CRYPTONOTE_NAME ".log")).string();
return (daemonizer::get_default_data_dir() / "testnet" / (CRYPTONOTE_NAME ".log")).u8string();
else if (testnet_devnet[1] && defaulted)
return (daemonizer::get_default_data_dir() / "devnet" /
std::string(CRYPTONOTE_NAME ".log")).string();
return (daemonizer::get_default_data_dir() / "devnet" / (CRYPTONOTE_NAME ".log")).u8string();
return val;
}
};

View File

@ -34,6 +34,7 @@
#include "common/scoped_message_writer.h"
#include "common/password.h"
#include "common/util.h"
#include "common/fs.h"
#include "cryptonote_core/cryptonote_core.h"
#include "daemonizer/daemonizer.h"
#include "misc_log_ex.h"
@ -54,7 +55,6 @@
#define LOKI_DEFAULT_LOG_CATEGORY "daemon"
namespace po = boost::program_options;
namespace bf = boost::filesystem;
using namespace std::literals;
@ -133,15 +133,16 @@ int main(int argc, char const * argv[])
return 0;
}
std::string config = command_line::get_arg(vm, daemon_args::arg_config_file);
boost::filesystem::path config_path(config);
boost::system::error_code ec;
if (bf::exists(config_path, ec))
auto config = fs::u8path(command_line::get_arg(vm, daemon_args::arg_config_file));
if (std::error_code ec; fs::exists(config, ec))
{
try
{
fs::ifstream cfg{config};
if (!cfg.is_open())
throw std::runtime_error{"Unable to open file"};
po::store(po::parse_config_file<char>(
config_path.string<std::string>().c_str(),
cfg,
po::options_description{}.add(core_settings).add(hidden_options)),
vm);
}
@ -174,12 +175,11 @@ int main(int argc, char const * argv[])
// relative path: relative to cwd
// Create data dir if it doesn't exist
boost::filesystem::path data_dir = boost::filesystem::absolute(
command_line::get_arg(vm, cryptonote::arg_data_dir));
auto data_dir = fs::absolute(fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)));
// FIXME: not sure on windows implementation default, needs further review
//bf::path relative_path_base = daemonizer::get_relative_path_base(vm);
bf::path relative_path_base = data_dir;
//fs::path relative_path_base = daemonizer::get_relative_path_base(vm);
fs::path relative_path_base = data_dir;
po::notify(vm);
@ -188,11 +188,11 @@ int main(int argc, char const * argv[])
// if log-file argument given:
// absolute path
// relative path: relative to data_dir
bf::path log_file_path {data_dir / std::string(CRYPTONOTE_NAME ".log")};
auto log_file_path = data_dir / CRYPTONOTE_NAME ".log";
if (!command_line::is_arg_defaulted(vm, daemon_args::arg_log_file))
log_file_path = command_line::get_arg(vm, daemon_args::arg_log_file);
if (!log_file_path.has_parent_path())
log_file_path = bf::absolute(log_file_path, relative_path_base);
if (log_file_path.is_relative())
log_file_path = fs::absolute(fs::relative(log_file_path, relative_path_base));
mlog_configure(log_file_path.string(), true, command_line::get_arg(vm, daemon_args::arg_max_log_file_size), command_line::get_arg(vm, daemon_args::arg_max_log_files));
// Set log level
@ -202,7 +202,7 @@ int main(int argc, char const * argv[])
}
// after logs initialized
tools::create_directories_if_necessary(data_dir.string());
tools::create_directories_if_necessary(data_dir);
#ifdef STACK_TRACE
tools::set_stack_trace_log(log_file_path.filename().string());

View File

@ -35,7 +35,7 @@ if(MSVC OR MINGW)
target_link_libraries(daemonizer
PUBLIC
common
Boost::filesystem
filesystem
Boost::program_options
PRIVATE
extra)

View File

@ -28,9 +28,9 @@
#pragma once
#include <boost/filesystem/path.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
#include "common/fs.h"
namespace daemonizer
{
@ -39,9 +39,9 @@ namespace daemonizer
, boost::program_options::options_description & normal_options
);
boost::filesystem::path get_default_data_dir();
fs::path get_default_data_dir();
boost::filesystem::path get_relative_path_base(
fs::path get_relative_path_base(
boost::program_options::variables_map const & vm
);

View File

@ -33,9 +33,6 @@
#include "common/file.h"
#include "common/command_line.h"
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
namespace daemonizer
{
namespace
@ -59,16 +56,16 @@ namespace daemonizer
command_line::add_arg(normal_options, arg_non_interactive);
}
inline boost::filesystem::path get_default_data_dir()
inline fs::path get_default_data_dir()
{
return boost::filesystem::absolute(tools::get_default_data_dir());
return fs::absolute(tools::get_default_data_dir());
}
inline boost::filesystem::path get_relative_path_base(
inline fs::path get_relative_path_base(
boost::program_options::variables_map const & vm
)
{
return boost::filesystem::current_path();
return fs::current_path();
}
template <typename Application, typename... Args>

View File

@ -36,8 +36,6 @@
#include "cryptonote_core/cryptonote_core.h"
#include <shlobj.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
namespace daemonizer
{
@ -92,7 +90,7 @@ namespace daemonizer
command_line::add_arg(hidden_options, arg_non_interactive);
}
inline boost::filesystem::path get_default_data_dir()
inline fs::path get_default_data_dir()
{
bool admin;
if (!windows::check_admin(admin))
@ -101,19 +99,19 @@ namespace daemonizer
}
if (admin)
{
return boost::filesystem::absolute(
tools::get_special_folder_path(CSIDL_COMMON_APPDATA, true) + "\\" + CRYPTONOTE_NAME
return fs::absolute(
tools::get_special_folder_path(CSIDL_COMMON_APPDATA, true) / CRYPTONOTE_NAME
);
}
else
{
return boost::filesystem::absolute(
tools::get_special_folder_path(CSIDL_APPDATA, true) + "\\" + CRYPTONOTE_NAME
return fs::absolute(
tools::get_special_folder_path(CSIDL_APPDATA, true) / CRYPTONOTE_NAME
);
}
}
inline boost::filesystem::path get_relative_path_base(
inline fs::path get_relative_path_base(
boost::program_options::variables_map const & vm
)
{
@ -130,7 +128,7 @@ namespace daemonizer
}
else
{
return boost::filesystem::current_path();
return fs::current_path();
}
}

View File

@ -61,5 +61,4 @@ target_link_libraries(dns_checks
epee
version
Boost::program_options
Boost::system
Boost::thread)

View File

@ -27,7 +27,6 @@
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem.hpp>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/tx_extra.h"
#include "cryptonote_core/blockchain.h"
@ -126,8 +125,6 @@ int main(int argc, char* argv[])
tools::on_startup();
boost::filesystem::path output_file_path;
po::options_description desc_cmd_only("Command line options");
po::options_description desc_cmd_sett("Command line options and settings options");
const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level};

View File

@ -38,6 +38,6 @@ target_link_libraries(gen_multisig
cryptonote_core
epee
Boost::program_options
Boost::filesystem
filesystem
version
extra)

View File

@ -39,7 +39,6 @@
#include <boost/program_options.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/format.hpp>
#include "include_base_utils.h"
#include "crypto/crypto.h" // for crypto::secret_key definition
#include "common/i18n.h"
#include "common/command_line.h"
@ -77,7 +76,7 @@ namespace
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
}
static bool generate_multisig(uint32_t threshold, uint32_t total, const std::string &basename, network_type nettype, bool create_address_file)
static bool generate_multisig(uint32_t threshold, uint32_t total, const fs::path& basename, network_type nettype, bool create_address_file)
{
tools::msg_writer() << (boost::format(genms::tr("Generating %u %u/%u multisig wallets")) % total % threshold % total).str();
@ -89,7 +88,8 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str
std::vector<std::shared_ptr<tools::wallet2>> wallets(total);
for (size_t n = 0; n < total; ++n)
{
std::string name = basename + "-" + std::to_string(n + 1);
fs::path name = basename;
name += "-" + std::to_string(n + 1);
wallets[n].reset(new tools::wallet2(nettype, 1, false));
wallets[n]->init("");
wallets[n]->generate(name, pwd_container->password(), rct::rct2sk(rct::skGen()), false, false, create_address_file);
@ -114,7 +114,8 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str
std::stringstream ss;
for (size_t n = 0; n < total; ++n)
{
std::string name = basename + "-" + std::to_string(n + 1);
fs::path name = basename;
name += "-" + std::to_string(n + 1);
std::vector<crypto::secret_key> skn;
std::vector<crypto::public_key> pkn;
for (size_t k = 0; k < total; ++k)
@ -190,7 +191,6 @@ int main(int argc, char* argv[])
bool testnet, devnet;
uint32_t threshold = 0, total = 0;
std::string basename;
testnet = command_line::get_arg(*vm, arg_testnet);
devnet = command_line::get_arg(*vm, arg_devnet);
@ -230,9 +230,10 @@ int main(int argc, char* argv[])
tools::fail_msg_writer() << (boost::format(genms::tr("Error: expected N > 1 and N <= M, but got N==%u and M==%d")) % threshold % total).str();
return 1;
}
fs::path basename;
if (!(*vm)["filename-base"].defaulted() && !command_line::get_arg(*vm, arg_filename_base).empty())
{
basename = command_line::get_arg(*vm, arg_filename_base);
basename = fs::u8path(command_line::get_arg(*vm, arg_filename_base));
}
else
{

View File

@ -28,7 +28,6 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unordered_set>
#include "include_base_utils.h"
#include "crypto/crypto.h"
#include "ringct/rctOps.h"
#include "cryptonote_basic/account.h"

View File

@ -41,6 +41,6 @@ target_link_libraries(p2p
net
miniupnpc
Boost::program_options
Boost::filesystem
filesystem
Boost::serialization
extra)

View File

@ -55,6 +55,7 @@
#include "net/fwd.h"
#include "common/command_line.h"
#include "common/periodic_task.h"
#include "common/fs.h"
PUSH_WARNINGS
DISABLE_VS_WARNINGS(4355)
@ -415,7 +416,7 @@ namespace nodetool
}
private:
std::string m_config_folder;
fs::path m_config_folder;
bool m_have_address;
bool m_first_connection_maker_call;

View File

@ -33,7 +33,6 @@
#include <algorithm>
#include <optional>
#include <boost/filesystem/operations.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <atomic>
#include <functional>
@ -42,6 +41,7 @@
#include <tuple>
#include <vector>
#include "cryptonote_config.h"
#include "version.h"
#include "string_tools.h"
#include "common/file.h"
@ -119,7 +119,7 @@ namespace nodetool
bool node_server<t_payload_net_handler>::init_config()
{
TRY_ENTRY();
auto storage = peerlist_storage::open(m_config_folder + "/" + P2P_NET_DATA_FILENAME);
auto storage = peerlist_storage::open(m_config_folder / P2P_NET_DATA_FILENAME);
if (storage)
m_peerlist_storage = std::move(*storage);
@ -708,14 +708,11 @@ namespace nodetool
memcpy(&m_network_id, &::config::NETWORK_ID, 16);
}
m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir);
m_config_folder = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir));
network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_);
if ((m_nettype == cryptonote::MAINNET && public_zone.m_port != std::to_string(::config::P2P_DEFAULT_PORT))
|| (m_nettype == cryptonote::TESTNET && public_zone.m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT))
|| (m_nettype == cryptonote::DEVNET && public_zone.m_port != std::to_string(::config::devnet::P2P_DEFAULT_PORT))) {
m_config_folder = m_config_folder + "/" + public_zone.m_port;
}
if (public_zone.m_port != std::to_string(cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT))
m_config_folder /= public_zone.m_port;
res = init_config();
CHECK_AND_ASSERT_MES(res, false, "Failed to init config.");
@ -905,7 +902,7 @@ namespace nodetool
if (!tools::create_directories_if_necessary(m_config_folder))
{
MWARNING("Failed to create data directory \"" << m_config_folder);
MWARNING("Failed to create data directory " << m_config_folder);
return false;
}
@ -913,7 +910,7 @@ namespace nodetool
for (auto& zone : m_network_zones)
zone.second.m_peerlist.get_peerlist(active);
const std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME;
const auto state_file_path = m_config_folder / P2P_NET_DATA_FILENAME;
if (!m_peerlist_storage.store(state_file_path, active))
{
MWARNING("Failed to save config to file " << state_file_path);

View File

@ -36,11 +36,11 @@
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/portable_binary_oarchive.hpp>
#include <boost/archive/portable_binary_iarchive.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/range/join.hpp>
#include <boost/serialization/version.hpp>
#include "net_peerlist_boost_serialization.h"
#include "common/fs.h"
namespace nodetool
@ -188,10 +188,9 @@ namespace nodetool
return std::nullopt;
}
std::optional<peerlist_storage> peerlist_storage::open(const std::string& path)
std::optional<peerlist_storage> peerlist_storage::open(const fs::path& path)
{
std::ifstream src_file{};
src_file.open( path , std::ios_base::binary | std::ios_base::in);
fs::ifstream src_file{path, std::ios::binary};
if(src_file.fail())
return std::nullopt;
@ -199,9 +198,11 @@ namespace nodetool
if (!out)
{
// if failed, try reading in unportable mode
boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists);
auto unportable = path;
unportable += ".unportable";
fs::copy_file(path, unportable, fs::copy_options::overwrite_existing);
src_file.close();
src_file.open( path , std::ios_base::binary | std::ios_base::in);
src_file.open(path, std::ios_base::binary);
if(src_file.fail())
return std::nullopt;
@ -237,10 +238,9 @@ namespace nodetool
return false;
}
bool peerlist_storage::store(const std::string& path, const peerlist_types& other) const
bool peerlist_storage::store(const fs::path& path, const peerlist_types& other) const
{
std::ofstream dest_file{};
dest_file.open( path , std::ios_base::binary | std::ios_base::out| std::ios::trunc);
fs::ofstream dest_file{path, std::ios::binary | std::ios::trunc};
if(dest_file.fail())
return false;

View File

@ -49,6 +49,7 @@
#include "net/local_ip.h"
#include "p2p_protocol_defs.h"
#include "common/random.h"
#include "common/fs.h"
namespace nodetool
{
@ -70,7 +71,7 @@ namespace nodetool
static std::optional<peerlist_storage> open(std::istream& src, const bool new_format);
//! \return Peers stored in file at `path`
static std::optional<peerlist_storage> open(const std::string& path);
static std::optional<peerlist_storage> open(const fs::path& path);
peerlist_storage(peerlist_storage&&) = default;
peerlist_storage(const peerlist_storage&) = delete;
@ -84,7 +85,7 @@ namespace nodetool
bool store(std::ostream& dest, const peerlist_types& other) const;
//! Save peers from `this` and `other` in one file at `path`.
bool store(const std::string& path, const peerlist_types& other) const;
bool store(const fs::path& path, const peerlist_types& other) const;
//! \return Peers in `zone` and from remove from `this`.
peerlist_types take_zone(epee::net_utils::zone zone);

View File

@ -43,7 +43,6 @@
#include "cryptonote_basic/tx_extra.h"
#include "cryptonote_core/loki_name_system.h"
#include "cryptonote_core/pulse.h"
#include "include_base_utils.h"
#include "loki_economy.h"
#include "string_tools.h"
#include "core_rpc_server.h"

View File

@ -128,7 +128,7 @@ lmq_rpc::lmq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog
// windows. In theory we could do some runtime detection to see if the Windows version is new
// enough to support unix domain sockets, but for now the Windows default is just "don't listen"
#ifndef _WIN32
locals.push_back("ipc://" + core.get_config_directory() + "/lokid.sock");
locals.push_back("ipc://" + core.get_config_directory().u8string() + "/lokid.sock");
#endif
} else if (locals.size() == 1 && locals[0] == "none") {
locals.clear();

View File

@ -38,11 +38,7 @@ target_link_libraries(simplewallet
cryptonote_core
mnemonics
Boost::program_options
Boost::filesystem
filesystem
icu
Boost::thread
extra)
if (WIN32)
target_link_libraries(simplewallet PRIVATE Boost::locale)
endif()

View File

@ -54,7 +54,6 @@
#include <boost/program_options.hpp>
#include <boost/format.hpp>
#include <lokimq/hex.h>
#include "include_base_utils.h"
#include "console_handler.h"
#include "common/i18n.h"
#include "common/command_line.h"
@ -86,11 +85,6 @@
#include "wallet/wallet_rpc_server_commands_defs.h"
#include "string_coding.h"
#ifdef WIN32
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
#endif
extern "C"
{
#include <sodium.h>
@ -611,17 +605,16 @@ namespace
fail_msg_writer() << sw::tr("There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information.");
}
bool check_file_overwrite(const std::string &filename)
bool check_file_overwrite(const fs::path& filename)
{
boost::system::error_code errcode;
if (boost::filesystem::exists(filename, errcode))
if (std::error_code ec; fs::exists(filename, ec))
{
if (boost::ends_with(filename, ".keys"))
if (filename.extension() == ".keys")
{
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.u8string();
return false;
}
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 command_line::is_yes(input_line((boost::format(sw::tr("File %s already exists. Are you sure to overwrite it?")) % filename.u8string()).str(), true));
}
return true;
}
@ -1201,7 +1194,7 @@ bool simple_wallet::export_multisig_main(const std::vector<std::string> &args, b
return false;
}
const std::string filename = args[0];
const fs::path filename = fs::u8path(args[0]);
if (!called_by_mms && m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename))
return true;
@ -1220,7 +1213,7 @@ bool simple_wallet::export_multisig_main(const std::vector<std::string> &args, b
bool r = m_wallet->save_to_file(filename, ciphertext);
if (!r)
{
fail_msg_writer() << tr("failed to save file ") << filename;
fail_msg_writer() << tr("failed to save file ") << filename.u8string();
return false;
}
}
@ -1232,7 +1225,7 @@ bool simple_wallet::export_multisig_main(const std::vector<std::string> &args, b
return false;
}
success_msg_writer() << tr("Multisig info exported to ") << filename;
success_msg_writer() << tr("Multisig info exported to ") << filename.u8string();
return true;
}
@ -1276,12 +1269,12 @@ bool simple_wallet::import_multisig_main(const std::vector<std::string> &args, b
}
else
{
const std::string &filename = args[n];
const fs::path filename = fs::u8path(args[n]);
std::string data;
bool r = m_wallet->load_from_file(filename, data);
if (!r)
{
fail_msg_writer() << tr("failed to read file ") << filename;
fail_msg_writer() << tr("failed to read file ") << filename.u8string();
return false;
}
info.push_back(std::move(data));
@ -1363,7 +1356,7 @@ bool simple_wallet::sign_multisig_main(const std::vector<std::string> &args, boo
SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;);
std::string filename = args[0];
fs::path filename = fs::u8path(args[0]);
std::vector<crypto::hash> txids;
uint32_t signers = 0;
try
@ -1427,7 +1420,7 @@ bool simple_wallet::sign_multisig_main(const std::vector<std::string> &args, boo
uint32_t threshold{0};
m_wallet->multisig(NULL, &threshold);
uint32_t signers_needed = threshold - signers - 1;
success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename << ", "
success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename.u8string() << ", "
<< signers_needed << " more signer(s) needed";
return true;
}
@ -1440,7 +1433,7 @@ bool simple_wallet::sign_multisig_main(const std::vector<std::string> &args, boo
txids_as_text += (", ");
txids_as_text += epee::string_tools::pod_to_hex(txid);
}
success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename << ", txid " << txids_as_text;
success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename.u8string() << ", txid " << txids_as_text;
success_msg_writer(true) << tr("It may be relayed to the network with submit_multisig");
}
return true;
@ -1482,7 +1475,7 @@ bool simple_wallet::submit_multisig_main(const std::vector<std::string> &args, b
SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;);
std::string filename = args[0];
fs::path filename = fs::u8path(args[0]);
try
{
tools::wallet2::multisig_tx_set txs;
@ -1560,7 +1553,7 @@ bool simple_wallet::export_raw_multisig(const std::vector<std::string> &args)
return true;
}
std::string filename = args[0];
fs::path filename = fs::u8path(args[0]);
if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename))
return true;
@ -1587,13 +1580,13 @@ bool simple_wallet::export_raw_multisig(const std::vector<std::string> &args)
for (auto &ptx: txs.m_ptx)
{
const crypto::hash txid = cryptonote::get_transaction_hash(ptx.tx);
const std::string filename = std::string("raw_multisig_loki_tx_") + epee::string_tools::pod_to_hex(txid);
const fs::path fn = fs::u8path("raw_multisig_loki_tx_" + epee::string_tools::pod_to_hex(txid));
if (!filenames.empty())
filenames += ", ";
filenames += filename;
if (!m_wallet->save_to_file(filename, cryptonote::tx_to_blob(ptx.tx)))
filenames += fn.u8string();
if (!m_wallet->save_to_file(fn, cryptonote::tx_to_blob(ptx.tx)))
{
fail_msg_writer() << tr("Failed to export multisig transaction to file ") << filename;
fail_msg_writer() << tr("Failed to export multisig transaction to file ") << fn.u8string();
return true;
}
}
@ -1671,7 +1664,8 @@ bool simple_wallet::set_ring(const std::vector<std::string> &args)
// try filename first
if (args.size() == 1)
{
if (!epee::file_io_utils::is_file_exist(args[0]))
auto ring_path = fs::u8path(args[0]);
if (std::error_code ec; !fs::exists(ring_path, ec) || ec)
{
fail_msg_writer() << tr("File doesn't exist");
return true;
@ -1893,7 +1887,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args)
{
m_wallet->blackball_output(std::make_pair(amount, offset));
}
else if (epee::file_io_utils::is_file_exist(args[0]))
else if (std::error_code ec; fs::exists(fs::u8path(args[0]), ec) && !ec)
{
std::vector<std::pair<uint64_t, uint64_t>> outputs;
char str[256];
@ -3322,7 +3316,7 @@ bool simple_wallet::set_log(const std::vector<std::string> &args)
bool simple_wallet::ask_wallet_create_if_needed()
{
LOG_PRINT_L3("simple_wallet::ask_wallet_create_if_needed() started");
std::string wallet_path;
fs::path wallet_path;
std::string confirm_creation;
bool wallet_name_valid = false;
bool keys_file_exists;
@ -3330,26 +3324,26 @@ bool simple_wallet::ask_wallet_create_if_needed()
do{
LOG_PRINT_L3("User asked to specify wallet file name.");
wallet_path = input_line(
wallet_path = fs::u8path(input_line(
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)" :
"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)")
);
));
if(std::cin.eof())
{
LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()");
return false;
}
if(!tools::wallet2::wallet_valid_path_format(wallet_path))
if(wallet_path.empty())
{
fail_msg_writer() << tr("Wallet name not valid. Please try again or use Ctrl-C to quit.");
fail_msg_writer() << tr("No wallet name provided. Please try again or use Ctrl-C to quit.");
wallet_name_valid = false;
}
else
{
tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists);
LOG_PRINT_L3("wallet_path: " << wallet_path << "");
LOG_PRINT_L3("wallet_path: " << wallet_path);
LOG_PRINT_L3("keys_file_exists: " << std::boolalpha << keys_file_exists << std::noboolalpha
<< " wallet_file_exists: " << std::boolalpha << wallet_file_exists << std::noboolalpha);
@ -3372,7 +3366,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
}
else if(wallet_file_exists && !keys_file_exists) //Yes wallet, no keys
{
fail_msg_writer() << tr("Key file not found. Failed to open wallet: ") << "\"" << wallet_path << "\". Exiting.";
fail_msg_writer() << tr("Key file not found. Failed to open wallet: ") << wallet_path << ". Exiting.";
return false;
}
else if(!wallet_file_exists && !keys_file_exists) //No wallet, no keys
@ -3381,7 +3375,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
if (!m_restoring)
{
std::string prompt = tr("No wallet found with that name. Confirm creation of new wallet named: ");
prompt += "\"" + wallet_path + "\"";
prompt += "\"" + wallet_path.u8string() + "\"";
confirm_creation = input_line(prompt, true);
if(std::cin.eof())
{
@ -4094,14 +4088,14 @@ bool simple_wallet::deinit()
//----------------------------------------------------------------------------------------------------
bool simple_wallet::handle_command_line(const boost::program_options::variables_map& vm)
{
m_wallet_file = command_line::get_arg(vm, arg_wallet_file);
m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet);
m_generate_from_device = command_line::get_arg(vm, arg_generate_from_device);
m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key);
m_generate_from_spend_key = command_line::get_arg(vm, arg_generate_from_spend_key);
m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys);
m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys);
m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json);
m_wallet_file = fs::u8path(command_line::get_arg(vm, arg_wallet_file));
m_generate_new = fs::u8path(command_line::get_arg(vm, arg_generate_new_wallet));
m_generate_from_device = fs::u8path(command_line::get_arg(vm, arg_generate_from_device));
m_generate_from_view_key = fs::u8path(command_line::get_arg(vm, arg_generate_from_view_key));
m_generate_from_spend_key = fs::u8path(command_line::get_arg(vm, arg_generate_from_spend_key));
m_generate_from_keys = fs::u8path(command_line::get_arg(vm, arg_generate_from_keys));
m_generate_from_multisig_keys = fs::u8path(command_line::get_arg(vm, arg_generate_from_multisig_keys));
m_generate_from_json = fs::u8path(command_line::get_arg(vm, arg_generate_from_json));
m_mnemonic_language = command_line::get_arg(vm, arg_mnemonic_language);
m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed);
m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet);
@ -4469,9 +4463,9 @@ std::optional<epee::wipeable_string> simple_wallet::new_wallet(const boost::prog
//----------------------------------------------------------------------------------------------------
std::optional<epee::wipeable_string> simple_wallet::open_wallet(const boost::program_options::variables_map& vm)
{
if (!tools::wallet2::wallet_valid_path_format(m_wallet_file))
if (m_wallet_file.empty())
{
fail_msg_writer() << tr("wallet file path not valid: ") << m_wallet_file;
fail_msg_writer() << tr("no wallet file provided");
return {};
}
@ -4637,9 +4631,9 @@ bool simple_wallet::save_watch_only(const std::vector<std::string> &args/* = std
try
{
std::string new_keys_filename;
fs::path new_keys_filename;
m_wallet->write_watch_only_wallet(m_wallet_file, pwd_container->password(), new_keys_filename);
success_msg_writer() << tr("Watch only wallet saved as: ") << new_keys_filename;
success_msg_writer() << tr("Watch only wallet saved as: ") << new_keys_filename.u8string();
}
catch (const std::exception &e)
{
@ -8076,9 +8070,9 @@ bool simple_wallet::get_tx_proof(const std::vector<std::string> &args)
try
{
std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : "");
const std::string filename = "loki_tx_proof";
const fs::path filename{"loki_tx_proof"};
if (m_wallet->save_to_file(filename, sig_str, true))
success_msg_writer() << tr("signature file saved to: ") << filename;
success_msg_writer() << tr("signature file saved to: ") << filename.u8string();
else
fail_msg_writer() << tr("failed to save signature file");
}
@ -8288,9 +8282,9 @@ bool simple_wallet::get_spend_proof(const std::vector<std::string> &args)
try
{
const std::string sig_str = m_wallet->get_spend_proof(txid, args.size() == 2 ? args[1] : "");
const std::string filename = "loki_spend_proof";
const fs::path filename{"loki_spend_proof"};
if (m_wallet->save_to_file(filename, sig_str, true))
success_msg_writer() << tr("signature file saved to: ") << filename;
success_msg_writer() << tr("signature file saved to: ") << filename.u8string();
else
fail_msg_writer() << tr("failed to save signature file");
}
@ -8377,9 +8371,9 @@ bool simple_wallet::get_reserve_proof(const std::vector<std::string> &args)
try
{
const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : "");
const std::string filename = "loki_reserve_proof";
const fs::path filename{"loki_reserve_proof"};
if (m_wallet->save_to_file(filename, sig_str, true))
success_msg_writer() << tr("signature file saved to: ") << filename;
success_msg_writer() << tr("signature file saved to: ") << filename.u8string();
else
fail_msg_writer() << tr("failed to save signature file");
}
@ -8654,20 +8648,20 @@ bool simple_wallet::export_transfers(const std::vector<std::string>& args_)
return true;
// output filename
std::string filename = (boost::format("output%u.csv") % m_current_subaddress_account).str();
std::string filename_str = (boost::format("output%u.csv") % m_current_subaddress_account).str();
if (local_args.size() > 0 && local_args[0].substr(0, 7) == "output=")
{
filename = local_args[0].substr(7, -1);
filename_str = local_args[0].substr(7);
local_args.erase(local_args.begin());
}
std::ofstream file(filename);
fs::ofstream file{fs::u8path(filename_str)};
const bool formatting = true;
file << m_wallet->transfers_to_csv(all_transfers, formatting);
file.close();
success_msg_writer() << tr("CSV exported to ") << filename;
success_msg_writer() << tr("CSV exported to ") << filename_str;
return true;
}
@ -9705,12 +9699,12 @@ bool simple_wallet::sign(const std::vector<std::string> &args)
index.minor = b;
}
const std::string &filename = args.back();
const fs::path filename = fs::u8path(args.back());
std::string data;
bool r = m_wallet->load_from_file(filename, data);
if (!r)
{
fail_msg_writer() << tr("failed to read file ") << filename;
fail_msg_writer() << tr("failed to read file ") << filename.u8string();
return true;
}
@ -9728,7 +9722,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args)
PRINT_USAGE(USAGE_VERIFY);
return true;
}
std::string filename = args[0];
fs::path filename = fs::u8path(args[0]);
std::string address_string = args[1];
std::string signature= args[2];
@ -9736,7 +9730,7 @@ bool simple_wallet::verify(const std::vector<std::string> &args)
bool r = m_wallet->load_from_file(filename, data);
if (!r)
{
fail_msg_writer() << tr("failed to read file ") << filename;
fail_msg_writer() << tr("failed to read file ") << filename.u8string();
return true;
}
@ -9777,7 +9771,7 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &args)
return true;
}
std::string filename = args[0];
fs::path filename = fs::u8path(args[0]);
if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename))
return true;
@ -9789,7 +9783,7 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &args)
bool requested_only = (args.size() == 2 && args[1] == "requested-only");
if (!m_wallet->export_key_images_to_file(filename, requested_only))
{
fail_msg_writer() << tr("failed to save file ") << filename;
fail_msg_writer() << tr("failed to save file ") << filename.u8string();
return true;
}
}
@ -9800,7 +9794,7 @@ bool simple_wallet::export_key_images(const std::vector<std::string> &args)
return true;
}
success_msg_writer() << tr("Signed key images exported to ") << filename;
success_msg_writer() << tr("Signed key images exported to ") << filename.u8string();
return true;
}
//----------------------------------------------------------------------------------------------------
@ -9823,7 +9817,7 @@ bool simple_wallet::import_key_images(const std::vector<std::string> &args)
return true;
}
std::string const &filename = args[0];
const fs::path filename = fs::u8path(args[0]);
LOCK_IDLE_SCOPE();
try
{
@ -9934,7 +9928,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args)
all = true;
}
std::string const &filename = args[filename_index];
const fs::path filename = fs::u8path(args[filename_index]);
if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename))
return true;
@ -9946,7 +9940,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args)
bool r = m_wallet->save_to_file(filename, data);
if (!r)
{
fail_msg_writer() << tr("failed to save file ") << filename;
fail_msg_writer() << tr("failed to save file ") << filename.u8string();
return true;
}
}
@ -9957,7 +9951,7 @@ bool simple_wallet::export_outputs(const std::vector<std::string> &args)
return true;
}
success_msg_writer() << tr("Outputs exported to ") << filename;
success_msg_writer() << tr("Outputs exported to ") << filename.u8string();
return true;
}
//----------------------------------------------------------------------------------------------------
@ -9973,13 +9967,13 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &args)
PRINT_USAGE(USAGE_IMPORT_OUTPUTS);
return true;
}
std::string filename = args[0];
const fs::path filename = fs::u8path(args[0]);
std::string data;
bool r = m_wallet->load_from_file(filename, data);
if (!r)
{
fail_msg_writer() << tr("failed to read file ") << filename;
fail_msg_writer() << tr("failed to read file ") << filename.u8string();
return true;
}
@ -9991,7 +9985,7 @@ bool simple_wallet::import_outputs(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
fail_msg_writer() << "Failed to import outputs " << filename << ": " << e.what();
fail_msg_writer() << "Failed to import outputs " << filename.u8string() << ": " << e.what();
return true;
}
@ -10199,13 +10193,14 @@ void simple_wallet::commit_or_save(std::vector<tools::wallet2::pending_tx>& ptx_
cryptonote::blobdata blob;
tx_to_blob(ptx.tx, blob);
const std::string blob_hex = epee::string_tools::buff_to_hex_nodelimer(blob);
const std::string filename = "raw_loki_tx" + (ptx_vector.size() == 1 ? "" : ("_" + std::to_string(i++)));
fs::path filename = fs::u8path("raw_loki_tx");
if (ptx_vector.size() > 1) filename += "_" + std::to_string(i++);
bool success = m_wallet->save_to_file(filename, blob_hex, true);
if (success) msg_buf += tr("Transaction successfully saved to ");
else msg_buf += tr("Failed to save transaction to ");
msg_buf += filename;
msg_buf += filename.u8string();
msg_buf += tr(", txid <");
msg_buf += epee::string_tools::pod_to_hex(txid);
msg_buf += ">";
@ -10231,11 +10226,6 @@ int main(int argc, char* argv[])
{
TRY_ENTRY();
#ifdef WIN32
// Activate UTF-8 support for Boost filesystem classes on Windows
std::locale::global(boost::locale::generator().generate(""));
boost::filesystem::path::imbue(std::locale());
#endif
setlocale(LC_CTYPE, "");
auto opt_size = command_line::boost_option_sizes();
@ -10996,7 +10986,7 @@ void simple_wallet::mms_export(const std::vector<std::string> &args)
bool valid_id = get_message_from_arg(args[0], m);
if (valid_id)
{
const std::string filename = "mms_message_content";
fs::path filename = fs::u8path("mms_message_content");
if (m_wallet->save_to_file(filename, m.content))
{
success_msg_writer() << tr("Message content saved to: ") << filename;

View File

@ -402,16 +402,15 @@ namespace cryptonote
};
private:
std::string m_wallet_file;
std::string m_generate_new;
std::string m_generate_from_device;
std::string m_generate_from_view_key;
std::string m_generate_from_spend_key;
std::string m_generate_from_keys;
std::string m_generate_from_multisig_keys;
std::string m_generate_from_json;
fs::path m_wallet_file;
fs::path m_generate_new;
fs::path m_generate_from_device;
fs::path m_generate_from_view_key;
fs::path m_generate_from_spend_key;
fs::path m_generate_from_keys;
fs::path m_generate_from_multisig_keys;
fs::path m_generate_from_json;
std::string m_mnemonic_language;
std::string m_import_path;
std::string m_subaddress_lookahead;
std::string m_restore_date; // optional - converted to m_restore_height

View File

@ -49,7 +49,7 @@ target_link_libraries(wallet
lmdb
rpc_http_client
Boost::serialization
Boost::filesystem
filesystem
Boost::thread
PRIVATE
OpenSSL::SSL

View File

@ -46,7 +46,7 @@ target_link_libraries(wallet_api
mnemonics
lmdb
Boost::serialization
Boost::filesystem
filesystem
Boost::thread
PRIVATE
extra)

View File

@ -77,7 +77,7 @@ std::vector<std::string> PendingTransactionImpl::txid() const
return txid;
}
bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite, bool blink)
bool PendingTransactionImpl::commit(const fs::path& filename, bool overwrite, bool blink)
{
LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size());
@ -85,10 +85,8 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite,
try {
// Save tx to file
if (!filename.empty()) {
boost::system::error_code ignore;
bool tx_file_exists = boost::filesystem::exists(filename, ignore);
if(tx_file_exists && !overwrite){
m_errorString = string(tr("Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:")) + filename;
if (std::error_code ec_ignore; fs::exists(filename, ec_ignore) && !overwrite){
m_errorString = std::string(tr("Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:")) + filename.u8string();
m_status = Status_Error;
LOG_ERROR(m_errorString);
return false;

View File

@ -45,7 +45,7 @@ public:
~PendingTransactionImpl();
int status() const override;
std::string errorString() const override;
bool commit(const std::string &filename = "", bool overwrite = false, bool blink = false) override;
bool commit(const fs::path& filename = "", bool overwrite = false, bool blink = false) override;
uint64_t amount() const override;
uint64_t dust() const override;
uint64_t fee() const override;

View File

@ -42,6 +42,7 @@
#include "subaddress_account.h"
#include "common_defines.h"
#include "common/util.h"
#include "common/fs.h"
#include "mnemonics/electrum-words.h"
#include "mnemonics/english.h"
@ -50,11 +51,6 @@
#include <unordered_map>
#include <thread>
#ifdef WIN32
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
#endif
using namespace std;
using namespace cryptonote;
@ -72,17 +68,16 @@ namespace {
// Connection timeout 30 sec
static const int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 1000 * 30;
std::string get_default_ringdb_path(cryptonote::network_type nettype)
fs::path get_default_ringdb_path(cryptonote::network_type nettype)
{
boost::filesystem::path dir = tools::get_default_data_dir();
auto dir = tools::get_default_data_dir();
// remove .loki, replace with .shared-ringdb
dir = dir.remove_filename();
dir /= ".shared-ringdb";
dir.replace_filename(".shared-ringdb");
if (nettype == cryptonote::TESTNET)
dir /= "testnet";
else if (nettype == cryptonote::DEVNET)
dir /= "devnet";
return dir.string();
return dir;
}
void checkMultisigWalletReady(const tools::wallet2* wallet) {
@ -402,14 +397,9 @@ uint64_t Wallet::maximumAllowedAmount()
return std::numeric_limits<uint64_t>::max();
}
void Wallet::init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console) {
#ifdef WIN32
// Activate UTF-8 support for Boost filesystem classes on Windows
std::locale::global(boost::locale::generator().generate(""));
boost::filesystem::path::imbue(std::locale());
#endif
void Wallet::init(const char *argv0, const char *default_log_base_name, const fs::path& log_path, bool console) {
epee::string_tools::set_module_name_and_folder(argv0);
mlog_configure(log_path.empty() ? mlog_get_default_log_path(default_log_base_name) : log_path.c_str(), console);
mlog_configure(log_path.empty() ? mlog_get_default_log_path(default_log_base_name) : log_path.u8string(), console);
}
void Wallet::debug(const std::string &category, const std::string &str) {
@ -496,7 +486,7 @@ WalletImpl::~WalletImpl()
LOG_PRINT_L1(__FUNCTION__ << " finished");
}
bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language)
bool WalletImpl::create(const fs::path& path, const std::string &password, const std::string &language)
{
clearStatus();
@ -533,7 +523,7 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co
return true;
}
bool WalletImpl::createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const
bool WalletImpl::createWatchOnly(const fs::path& path, const std::string &password, const std::string &language) const
{
clearStatus();
std::unique_ptr<tools::wallet2> view_wallet(new tools::wallet2(m_wallet->nettype()));
@ -599,7 +589,7 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas
return true;
}
bool WalletImpl::recoverFromKeys(const std::string &path,
bool WalletImpl::recoverFromKeys(const fs::path& path,
const std::string &language,
const std::string &address_string,
const std::string &viewkey_string,
@ -608,7 +598,7 @@ bool WalletImpl::recoverFromKeys(const std::string &path,
return recoverFromKeysWithPassword(path, "", language, address_string, viewkey_string, spendkey_string);
}
bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
bool WalletImpl::recoverFromKeysWithPassword(const fs::path& path,
const std::string &password,
const std::string &language,
const std::string &address_string,
@ -704,7 +694,7 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
return true;
}
bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &password, const std::string &device_name)
bool WalletImpl::recoverFromDevice(const fs::path& path, const std::string &password, const std::string &device_name)
{
clearStatus();
m_recoveringFromSeed = false;
@ -726,7 +716,7 @@ Wallet::Device WalletImpl::getDeviceType() const
return static_cast<Wallet::Device>(m_wallet->get_device_type());
}
bool WalletImpl::open(const std::string &path, const std::string &password)
bool WalletImpl::open(const fs::path& path, const std::string &password)
{
clearStatus();
m_recoveringFromSeed = false;
@ -752,12 +742,12 @@ bool WalletImpl::open(const std::string &path, const std::string &password)
return status() == Status_Ok;
}
bool WalletImpl::recover(const std::string &path, const std::string &seed)
bool WalletImpl::recover(const fs::path& path, const std::string &seed)
{
return recover(path, "", seed);
}
bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/)
bool WalletImpl::recover(const fs::path& path, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/)
{
clearStatus();
m_errorString.clear();
@ -935,12 +925,12 @@ std::string WalletImpl::publicMultisigSignerKey() const
}
}
std::string WalletImpl::path() const
fs::path WalletImpl::path() const
{
return m_wallet->path();
}
bool WalletImpl::store(const std::string &path)
bool WalletImpl::store(const fs::path& path)
{
clearStatus();
try {
@ -958,12 +948,12 @@ bool WalletImpl::store(const std::string &path)
return true;
}
string WalletImpl::filename() const
fs::path WalletImpl::filename() const
{
return m_wallet->get_wallet_file();
}
string WalletImpl::keysFilename() const
fs::path WalletImpl::keysFilename() const
{
return m_wallet->get_keys_file();
}
@ -1154,7 +1144,7 @@ int WalletImpl::autoRefreshInterval() const
return m_refreshIntervalMillis;
}
UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_filename) {
UnsignedTransaction* WalletImpl::loadUnsignedTx(const fs::path& unsigned_filename) {
clearStatus();
UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this);
if (!m_wallet->load_unsigned_tx(unsigned_filename, transaction->m_unsigned_tx_set)){
@ -1175,7 +1165,7 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}
bool WalletImpl::submitTransaction(const string &fileName) {
bool WalletImpl::submitTransaction(const fs::path& fileName) {
clearStatus();
std::unique_ptr<PendingTransactionImpl> transaction(new PendingTransactionImpl(*this));
@ -1193,7 +1183,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
bool WalletImpl::exportKeyImages(const string &filename)
bool WalletImpl::exportKeyImages(const fs::path& filename)
{
if (m_wallet->watch_only())
{
@ -1205,7 +1195,7 @@ bool WalletImpl::exportKeyImages(const string &filename)
{
if (!m_wallet->export_key_images_to_file(filename, false /* requested_ki_only */))
{
setStatusError(tr("failed to save file ") + filename);
setStatusError(tr("failed to save file ") + filename.u8string());
return false;
}
}
@ -1218,7 +1208,7 @@ bool WalletImpl::exportKeyImages(const string &filename)
return true;
}
bool WalletImpl::importKeyImages(const string &filename)
bool WalletImpl::importKeyImages(const fs::path& filename)
{
if (!trustedDaemon()) {
setStatusError(tr("Key images can only be imported with a trusted daemon"));

View File

@ -54,14 +54,14 @@ class WalletImpl : public Wallet
public:
WalletImpl(NetworkType nettype = MAINNET, uint64_t kdf_rounds = 1);
~WalletImpl();
bool create(const std::string &path, const std::string &password,
bool create(const fs::path& path, const std::string &password,
const std::string &language);
bool createWatchOnly(const std::string &path, const std::string &password,
bool createWatchOnly(const fs::path& path, const std::string &password,
const std::string &language) const override;
bool open(const std::string &path, const std::string &password);
bool recover(const std::string &path,const std::string &password,
bool open(const fs::path& path, const std::string &password);
bool recover(const fs::path& path,const std::string &password,
const std::string &seed, const std::string &seed_offset = {});
bool recoverFromKeysWithPassword(const std::string &path,
bool recoverFromKeysWithPassword(const fs::path& path,
const std::string &password,
const std::string &language,
const std::string &address_string,
@ -69,14 +69,14 @@ public:
const std::string &spendkey_string = "");
// following two methods are deprecated since they create passwordless wallets
// use the two equivalent methods above
bool recover(const std::string &path, const std::string &seed);
bool recover(const fs::path& path, const std::string &seed);
// deprecated: use recoverFromKeysWithPassword() instead
bool recoverFromKeys(const std::string &path,
bool recoverFromKeys(const fs::path& path,
const std::string &language,
const std::string &address_string,
const std::string &viewkey_string,
const std::string &spendkey_string = "");
bool recoverFromDevice(const std::string &path,
bool recoverFromDevice(const fs::path& path,
const std::string &password,
const std::string &device_name);
Device getDeviceType() const override;
@ -98,10 +98,10 @@ public:
std::string secretSpendKey() const override;
std::string publicSpendKey() const override;
std::string publicMultisigSignerKey() const override;
std::string path() const override;
bool store(const std::string &path) override;
std::string filename() const override;
std::string keysFilename() const override;
fs::path path() const override;
bool store(const fs::path& path) override;
fs::path filename() const override;
fs::path keysFilename() const override;
bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit = 0, const std::string &daemon_username = "", const std::string &daemon_password = "", bool use_ssl = false, bool lightWallet = false) override;
bool connectToDaemon() override;
ConnectionStatus connected() const override;
@ -162,10 +162,10 @@ public:
uint32_t subaddr_account = 0,
std::set<uint32_t> subaddr_indices = {}) override;
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
bool exportKeyImages(const std::string &filename) override;
bool importKeyImages(const std::string &filename) override;
bool submitTransaction(const fs::path& fileName) override;
virtual UnsignedTransaction* loadUnsignedTx(const fs::path& unsigned_filename) override;
bool exportKeyImages(const fs::path& filename) override;
bool importKeyImages(const fs::path& filename) override;
void disposeTransaction(PendingTransaction * t) override;
// TODO(loki): Implement

View File

@ -39,6 +39,7 @@
#include <iostream>
#include <stdexcept>
#include <optional>
#include "common/fs.h"
// Public interface for libwallet library
namespace Monero {
@ -69,7 +70,7 @@ struct PendingTransaction
virtual int status() const = 0;
virtual std::string errorString() const = 0;
// commit transaction or save to file if filename is provided.
virtual bool commit(const std::string &filename = "", bool overwrite = false, bool blink = false) = 0;
virtual bool commit(const fs::path& filename = "", bool overwrite = false, bool blink = false) = 0;
virtual uint64_t amount() const = 0;
virtual uint64_t dust() const = 0;
virtual uint64_t fee() const = 0;
@ -438,7 +439,7 @@ struct Wallet
virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; };
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
std::string mainAddress() const { return address(0, 0); }
virtual std::string path() const = 0;
virtual fs::path path() const = 0;
virtual NetworkType nettype() const = 0;
bool mainnet() const { return nettype() == MAINNET; }
bool testnet() const { return nettype() == TESTNET; }
@ -494,17 +495,17 @@ struct Wallet
* to store to the same file - just pass empty string;
* \return
*/
virtual bool store(const std::string &path) = 0;
virtual bool store(const fs::path& path) = 0;
/*!
* \brief filename - returns wallet filename
* \return
*/
virtual std::string filename() const = 0;
virtual fs::path filename() const = 0;
/*!
* \brief keysFilename - returns keys filename. usually this formed as "wallet_filename".keys
* \return
*/
virtual std::string keysFilename() const = 0;
virtual fs::path keysFilename() const = 0;
/*!
* \brief init - initializes wallet with daemon connection params.
* if daemon_address is local address, "trusted daemon" will be set to true forcibly
@ -526,7 +527,7 @@ struct Wallet
* \param language
* \return - true if created successfully
*/
virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0;
virtual bool createWatchOnly(const fs::path& path, const std::string& password, const std::string& language) const = 0;
/*!
* \brief setRefreshFromBlockHeight - start refresh from block height on recover
@ -660,7 +661,7 @@ struct Wallet
static uint64_t maximumAllowedAmount();
// Easylogger wrapper
static void init(const char *argv0, const char *default_log_base_name) { init(argv0, default_log_base_name, "", true); }
static void init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console);
static void init(const char* argv0, const char* default_log_base_name, const fs::path& log_path, bool console);
static void debug(const std::string &category, const std::string &str);
static void info(const std::string &category, const std::string &str);
static void warning(const std::string &category, const std::string &str);
@ -847,13 +848,13 @@ struct Wallet
* \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status()
* after object returned
*/
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
virtual UnsignedTransaction * loadUnsignedTx(const fs::path& unsigned_filename) = 0;
/*!
* \brief submitTransaction - submits transaction in signed tx file
* \return - true on success
*/
virtual bool submitTransaction(const std::string &fileName) = 0;
virtual bool submitTransaction(const fs::path& fileName) = 0;
/*!
@ -878,14 +879,14 @@ struct Wallet
* \param filename
* \return - true on success
*/
virtual bool exportKeyImages(const std::string &filename) = 0;
virtual bool exportKeyImages(const fs::path& filename) = 0;
/*!
* \brief importKeyImages - imports key images from file
* \param filename
* \return - true on success
*/
virtual bool importKeyImages(const std::string &filename) = 0;
virtual bool importKeyImages(const fs::path& filename) = 0;
virtual TransactionHistory * history() = 0;
@ -1043,7 +1044,7 @@ struct WalletManagerBase
* \param kdf_rounds Number of rounds for key derivation function
* \return Wallet instance (Wallet::status() needs to be called to check if created successfully)
*/
virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) = 0;
virtual Wallet* createWallet(const fs::path& path, const std::string& password, const std::string& language, NetworkType nettype, uint64_t kdf_rounds = 1) = 0;
Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) // deprecated
{
return createWallet(path, password, language, testnet ? TESTNET : MAINNET);
@ -1058,7 +1059,7 @@ struct WalletManagerBase
* \param listener Wallet listener to set to the wallet after creation
* \return Wallet instance (Wallet::status() needs to be called to check if opened successfully)
*/
virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0;
virtual Wallet* openWallet(const fs::path& path, const std::string& password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0;
Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated
{
return openWallet(path, password, testnet ? TESTNET : MAINNET);
@ -1075,7 +1076,7 @@ struct WalletManagerBase
* \param seed_offset Seed offset passphrase (optional)
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
virtual Wallet* recoveryWallet(const fs::path& path, const std::string& password, const std::string& mnemonic,
NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1,
const std::string &seed_offset = {}) = 0;
Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic,
@ -1093,7 +1094,7 @@ struct WalletManagerBase
* \param restoreHeight restore from start height
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight = 0) = 0;
virtual Wallet* recoveryWallet(const fs::path& path, const std::string& mnemonic, NetworkType nettype, uint64_t restoreHeight = 0) = 0;
Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated
{
return recoveryWallet(path, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight);
@ -1112,15 +1113,16 @@ struct WalletManagerBase
* \param kdf_rounds Number of rounds for key derivation function
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * createWalletFromKeys(const std::string &path,
const std::string &password,
const std::string &language,
NetworkType nettype,
uint64_t restoreHeight,
const std::string &addressString,
const std::string &viewKeyString,
const std::string &spendKeyString = "",
uint64_t kdf_rounds = 1) = 0;
virtual Wallet* createWalletFromKeys(
const fs::path& path,
const std::string& password,
const std::string& language,
NetworkType nettype,
uint64_t restoreHeight,
const std::string& addressString,
const std::string& viewKeyString,
const std::string& spendKeyString = "",
uint64_t kdf_rounds = 1) = 0;
Wallet * createWalletFromKeys(const std::string &path,
const std::string &password,
const std::string &language,
@ -1145,13 +1147,14 @@ struct WalletManagerBase
* \param spendKeyString spend key (optional)
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * createWalletFromKeys(const std::string &path,
const std::string &language,
NetworkType nettype,
uint64_t restoreHeight,
const std::string &addressString,
const std::string &viewKeyString,
const std::string &spendKeyString = "") = 0;
virtual Wallet* createWalletFromKeys(
const fs::path& path,
const std::string& language,
NetworkType nettype,
uint64_t restoreHeight,
const std::string& addressString,
const std::string& viewKeyString,
const std::string& spendKeyString = "") = 0;
Wallet * createWalletFromKeys(const std::string &path,
const std::string &language,
bool testnet,
@ -1200,7 +1203,7 @@ struct WalletManagerBase
* @param path - filename
* @return - true if wallet exists
*/
virtual bool walletExists(const std::string &path) = 0;
virtual bool walletExists(const fs::path& path) = 0;
/*!
* @brief verifyWalletPassword - check if the given filename is the wallet
@ -1214,7 +1217,7 @@ struct WalletManagerBase
* This function will fail when the wallet keys file is opened because the wallet program locks the keys file.
* In this case, Wallet::unlockKeysFile() and Wallet::lockKeysFile() need to be called before and after the call to this function, respectively.
*/
virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0;
virtual bool verifyWalletPassword(const fs::path& keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0;
/*!
* \brief determine the key storage for the specified wallet file
@ -1226,14 +1229,14 @@ struct WalletManagerBase
* for verification only - determines key storage hardware
*
*/
virtual bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const = 0;
virtual bool queryWalletDevice(Wallet::Device& device_type, const fs::path& keys_file_name, const std::string& password, uint64_t kdf_rounds = 1) const = 0;
/*!
* \brief findWallets - searches for the wallet files by given path name recursively
* \param path - starting point to search
* \return - list of strings with found wallets (absolute paths);
*/
virtual std::vector<std::string> findWallets(const std::string &path) = 0;
virtual std::vector<std::string> findWallets(const fs::path& path) = 0;
//! returns verbose error string regarding last error;
virtual std::string errorString() const = 0;

View File

@ -38,14 +38,14 @@
#include "common/dns_utils.h"
#include "common/util.h"
#include "version.h"
#include <boost/filesystem.hpp>
#include "common/fs.h"
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "WalletAPI"
namespace Monero {
Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password,
Wallet* WalletManagerImpl::createWallet(const fs::path& path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
@ -53,7 +53,7 @@ Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::stri
return wallet;
}
Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener)
Wallet* WalletManagerImpl::openWallet(const fs::path& path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
wallet->setListener(listener);
@ -67,12 +67,12 @@ Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string
return wallet;
}
Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight)
Wallet* WalletManagerImpl::recoveryWallet(const fs::path& path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight)
{
return recoveryWallet(path, "", mnemonic, nettype, restoreHeight);
}
Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
Wallet* WalletManagerImpl::createWalletFromKeys(const fs::path& path,
const std::string &language,
NetworkType nettype,
uint64_t restoreHeight,
@ -84,7 +84,7 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
addressString, viewKeyString, spendKeyString);
}
Wallet *WalletManagerImpl::recoveryWallet(const std::string &path,
Wallet* WalletManagerImpl::recoveryWallet(const fs::path& path,
const std::string &password,
const std::string &mnemonic,
NetworkType nettype,
@ -100,7 +100,7 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path,
return wallet;
}
Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
Wallet* WalletManagerImpl::createWalletFromKeys(const fs::path& path,
const std::string &password,
const std::string &language,
NetworkType nettype,
@ -118,7 +118,7 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path,
return wallet;
}
Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
Wallet* WalletManagerImpl::createWalletFromDevice(const fs::path& path,
const std::string &password,
NetworkType nettype,
const std::string &deviceName,
@ -161,7 +161,7 @@ bool WalletManagerImpl::closeWallet(Wallet *wallet, bool store)
return result;
}
bool WalletManagerImpl::walletExists(const std::string &path)
bool WalletManagerImpl::walletExists(const fs::path& path)
{
bool keys_file_exists;
bool wallet_file_exists;
@ -172,12 +172,12 @@ bool WalletManagerImpl::walletExists(const std::string &path)
return false;
}
bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds) const
bool WalletManagerImpl::verifyWalletPassword(const fs::path& keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds) const
{
return tools::wallet2::verify_password(keys_file_name, password, no_spend_key, hw::get_device("default"), kdf_rounds);
}
bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const
bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const fs::path& keys_file_name, const std::string &password, uint64_t kdf_rounds) const
{
hw::device::device_type type;
bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds);
@ -185,29 +185,28 @@ bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std
return r;
}
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
std::vector<std::string> WalletManagerImpl::findWallets(const fs::path& path)
{
std::vector<std::string> result;
boost::filesystem::path work_dir(path);
// return empty result if path doesn't exist
if(!boost::filesystem::is_directory(path)){
if (!fs::is_directory(path)){
return result;
}
boost::filesystem::recursive_directory_iterator end_itr; // Default ctor yields past-the-end
for (boost::filesystem::recursive_directory_iterator itr(path); itr != end_itr; ++itr) {
fs::recursive_directory_iterator end_itr; // Default ctor yields past-the-end
for (auto& p : fs::recursive_directory_iterator{path}) {
// Skip if not a file
if (!boost::filesystem::is_regular_file(itr->status()))
if (!p.is_regular_file())
continue;
std::string filename = itr->path().filename().string();
auto filename = p.path();
LOG_PRINT_L3("Checking filename: " << filename);
if (tools::ends_with(filename, ".keys")) {
if (filename.extension() == ".keys") {
// if keys file found, checking if there's wallet file itself
filename.erase(filename.size() - 5);
if (boost::filesystem::exists(filename)) {
filename.replace_extension();
if (fs::exists(filename)) {
LOG_PRINT_L3("Found wallet: " << filename);
result.push_back(std::move(filename));
result.push_back(filename.u8string());
}
}
}

View File

@ -38,17 +38,17 @@ namespace Monero {
class WalletManagerImpl : public WalletManagerBase
{
public:
Wallet * createWallet(const std::string &path, const std::string &password,
Wallet* createWallet(const fs::path& path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) override;
Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override;
virtual Wallet * recoveryWallet(const std::string &path,
Wallet* openWallet(const fs::path& path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override;
virtual Wallet * recoveryWallet(const fs::path& path,
const std::string &password,
const std::string &mnemonic,
NetworkType nettype,
uint64_t restoreHeight,
uint64_t kdf_rounds = 1,
const std::string &seed_offset = {}) override;
virtual Wallet * createWalletFromKeys(const std::string &path,
virtual Wallet * createWalletFromKeys(const fs::path& path,
const std::string &password,
const std::string &language,
NetworkType nettype,
@ -58,16 +58,16 @@ public:
const std::string &spendKeyString = "",
uint64_t kdf_rounds = 1) override;
// next two methods are deprecated - use the above version which allow setting of a password
virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight) override;
virtual Wallet * recoveryWallet(const fs::path& path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight) override;
// deprecated: use createWalletFromKeys(..., password, ...) instead
virtual Wallet * createWalletFromKeys(const std::string &path,
virtual Wallet * createWalletFromKeys(const fs::path& path,
const std::string &language,
NetworkType nettype,
uint64_t restoreHeight,
const std::string &addressString,
const std::string &viewKeyString,
const std::string &spendKeyString = "") override;
virtual Wallet * createWalletFromDevice(const std::string &path,
virtual Wallet * createWalletFromDevice(const fs::path& path,
const std::string &password,
NetworkType nettype,
const std::string &deviceName,
@ -76,10 +76,10 @@ public:
uint64_t kdf_rounds = 1,
WalletListener * listener = nullptr) override;
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const override;
std::vector<std::string> findWallets(const std::string &path) override;
bool walletExists(const fs::path& path) override;
bool verifyWalletPassword(const fs::path& keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
bool queryWalletDevice(Wallet::Device& device_type, const fs::path& keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const override;
std::vector<std::string> findWallets(const fs::path& path) override;
std::string errorString() const override;
void setDaemonAddress(std::string address) override;
bool connected(uint32_t *version = NULL) override;

View File

@ -33,11 +33,11 @@
#include <boost/algorithm/string.hpp>
#include <fstream>
#include <sstream>
#include "file_io_utils.h"
#include "wallet_errors.h"
#include "serialization/binary_utils.h"
#include "common/base58.h"
#include "common/util.h"
#include "common/file.h"
#include "string_tools.h"
@ -688,7 +688,7 @@ void message_store::get_sanitized_message_text(const message &m, std::string &sa
}
}
void message_store::write_to_file(const multisig_wallet_state &state, const std::string &filename)
void message_store::write_to_file(const multisig_wallet_state &state, const fs::path &filename)
{
std::stringstream oss;
boost::archive::portable_binary_oarchive ar(oss);
@ -711,15 +711,13 @@ void message_store::write_to_file(const multisig_wallet_state &state, const std:
boost::archive::portable_binary_oarchive file_ar(file_oss);
file_ar << write_file_data;
bool success = epee::file_io_utils::save_string_to_file(filename, file_oss.str());
bool success = tools::dump_file(filename, file_oss.str());
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_save_error, filename);
}
void message_store::read_from_file(const multisig_wallet_state &state, const std::string &filename)
void message_store::read_from_file(const multisig_wallet_state &state, const fs::path &filename)
{
boost::system::error_code ignored_ec;
bool file_exists = boost::filesystem::exists(filename, ignored_ec);
if (!file_exists)
if (std::error_code ec; !fs::exists(filename, ec))
{
// Simply do nothing if the file is not there; allows e.g. easy recovery
// from problems with the MMS by deleting the file
@ -728,7 +726,7 @@ void message_store::read_from_file(const multisig_wallet_state &state, const std
}
std::string buf;
bool success = epee::file_io_utils::load_file_to_string(filename, buf);
bool success = tools::slurp_file(filename, buf);
THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_read_error, filename);
file_data read_file_data;

Some files were not shown because too many files have changed in this diff Show More