Skip to content

Commit

Permalink
Merge pull request #7102 from Icinga/feature/boost-fs-7101
Browse files Browse the repository at this point in the history
Replace self-written filesystem ops with boost.filesystem
  • Loading branch information
Michael Friedrich authored Apr 25, 2019
2 parents 4d05ecc + 5afef10 commit 0438c86
Show file tree
Hide file tree
Showing 18 changed files with 66 additions and 343 deletions.
4 changes: 3 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,15 @@ if(LOGROTATE_HAS_SU)
set(LOGROTATE_USE_SU "\n\tsu ${ICINGA2_USER} ${ICINGA2_GROUP}")
endif()

find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS context coroutine date_time thread system program_options regex REQUIRED)
find_package(Boost ${BOOST_MIN_VERSION} COMPONENTS context coroutine date_time filesystem thread system program_options regex REQUIRED)

# Boost.Coroutine2 (the successor of Boost.Coroutine)
# (1) doesn't even exist in old Boost versions and
# (2) isn't supported by ASIO, yet.
add_definitions(-DBOOST_COROUTINES_NO_DEPRECATION_WARNING)

add_definitions(-DBOOST_FILESYSTEM_NO_DEPRECATED)

link_directories(${Boost_LIBRARY_DIRS})
include_directories(${Boost_INCLUDE_DIRS})

Expand Down
11 changes: 1 addition & 10 deletions lib/base/configobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -505,16 +505,7 @@ void ConfigObject::DumpObjects(const String& filename, int attributeTypes)

fp.close();

#ifdef _WIN32
_unlink(filename.CStr());
#endif /* _WIN32 */

if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempFilename));
}
Utility::RenameFile(tempFilename, filename);
}

void ConfigObject::RestoreObject(const String& message, int attributeTypes)
Expand Down
11 changes: 1 addition & 10 deletions lib/base/scriptglobal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,6 @@ void ScriptGlobal::WriteToFile(const String& filename)

fp.close();

#ifdef _WIN32
_unlink(filename.CStr());
#endif /* _WIN32 */

if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempFilename));
}
Utility::RenameFile(tempFilename, filename);
}

136 changes: 33 additions & 103 deletions lib/base/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
#include "base/objectlock.hpp"
#include <cstdint>
#include <mmatch.h>
#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/tss.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/replace.hpp>
Expand Down Expand Up @@ -249,47 +252,7 @@ bool Utility::CidrMatch(const String& pattern, const String& ip)
*/
String Utility::DirName(const String& path)
{
char *dir;

#ifdef _WIN32
String dupPath = path;

/* PathRemoveFileSpec doesn't properly handle forward slashes. */
for (char& ch : dupPath) {
if (ch == '/')
ch = '\\';
}

dir = strdup(dupPath.CStr());
#else /* _WIN32 */
dir = strdup(path.CStr());
#endif /* _WIN32 */

if (!dir)
BOOST_THROW_EXCEPTION(std::bad_alloc());

String result;

#ifndef _WIN32
result = dirname(dir);
#else /* _WIN32 */
if (dir[0] != 0 && !PathRemoveFileSpec(dir)) {
free(dir);

BOOST_THROW_EXCEPTION(win32_error()
<< boost::errinfo_api_function("PathRemoveFileSpec")
<< errinfo_win32_error(GetLastError()));
}

result = dir;

if (result.IsEmpty())
result = ".";
#endif /* _WIN32 */

free(dir);

return result;
return boost::filesystem::path(path.Begin(), path.End()).parent_path().string();
}

/**
Expand All @@ -300,21 +263,7 @@ String Utility::DirName(const String& path)
*/
String Utility::BaseName(const String& path)
{
char *dir = strdup(path.CStr());
String result;

if (!dir)
BOOST_THROW_EXCEPTION(std::bad_alloc());

#ifndef _WIN32
result = basename(dir);
#else /* _WIN32 */
result = PathFindFileName(dir);
#endif /* _WIN32 */

free(dir);

return result;
return boost::filesystem::path(path.Begin(), path.End()).filename().string();
}

/**
Expand Down Expand Up @@ -753,38 +702,18 @@ void Utility::MkDirP(const String& path, int mode)
}
}

void Utility::RemoveDirRecursive(const String& path)
void Utility::Remove(const String& path)
{
std::vector<String> paths;
Utility::GlobRecursive(path, "*", std::bind(&Utility::CollectPaths, _1, std::ref(paths)), GlobFile | GlobDirectory);
namespace fs = boost::filesystem;

/* This relies on the fact that GlobRecursive lists the parent directory
* first before recursing into subdirectories.
*/
std::reverse(paths.begin(), paths.end());

for (const String& path : paths) {
if (remove(path.CStr()) < 0)
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("remove")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(path));
}

#ifndef _WIN32
if (rmdir(path.CStr()) < 0)
#else /* _WIN32 */
if (_rmdir(path.CStr()) < 0)
#endif /* _WIN32 */
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rmdir")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(path));
(void)fs::remove(fs::path(path.Begin(), path.End()));
}

void Utility::CollectPaths(const String& path, std::vector<String>& paths)
void Utility::RemoveDirRecursive(const String& path)
{
paths.push_back(path);
namespace fs = boost::filesystem;

(void)fs::remove_all(fs::path(path.Begin(), path.End()));
}

/*
Expand All @@ -793,10 +722,20 @@ void Utility::CollectPaths(const String& path, std::vector<String>& paths)
*/
void Utility::CopyFile(const String& source, const String& target)
{
std::ifstream ifs(source.CStr(), std::ios::binary);
std::ofstream ofs(target.CStr(), std::ios::binary | std::ios::trunc);
namespace fs = boost::filesystem;

ofs << ifs.rdbuf();
fs::copy_file(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()), fs::copy_option::overwrite_if_exists);
}

/*
* Renames a source file to a target location.
* Caller must ensure that the target's base directory exists and is writable.
*/
void Utility::RenameFile(const String& source, const String& target)
{
namespace fs = boost::filesystem;

fs::rename(fs::path(source.Begin(), source.End()), fs::path(target.Begin(), target.End()));
}

/*
Expand Down Expand Up @@ -1339,13 +1278,11 @@ tm Utility::LocalTime(time_t ts)

bool Utility::PathExists(const String& path)
{
#ifndef _WIN32
struct stat statbuf;
return (lstat(path.CStr(), &statbuf) >= 0);
#else /* _WIN32 */
struct _stat statbuf;
return (_stat(path.CStr(), &statbuf) >= 0);
#endif /* _WIN32 */
namespace fs = boost::filesystem;

boost::system::error_code ec;

return fs::exists(fs::path(path.Begin(), path.End()), ec) && !ec;
}

Value Utility::LoadJsonFile(const String& path)
Expand All @@ -1365,23 +1302,16 @@ Value Utility::LoadJsonFile(const String& path)

void Utility::SaveJsonFile(const String& path, int mode, const Value& value)
{
namespace fs = boost::filesystem;

std::fstream fp;
String tempFilename = Utility::CreateTempFile(path + ".XXXXXX", mode, fp);

fp.exceptions(std::ofstream::failbit | std::ofstream::badbit);
fp << JsonEncode(value);
fp.close();

#ifdef _WIN32
_unlink(path.CStr());
#endif /* _WIN32 */

if (rename(tempFilename.CStr(), path.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempFilename));
}
RenameFile(tempFilename, path);
}

static void HexEncode(char ch, std::ostream& os)
Expand Down
3 changes: 2 additions & 1 deletion lib/base/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,10 @@ class Utility

static bool PathExists(const String& path);

static void Remove(const String& path);
static void RemoveDirRecursive(const String& path);
static void CopyFile(const String& source, const String& target);
static void RenameFile(const String& source, const String& target);

static Value LoadJsonFile(const String& path);
static void SaveJsonFile(const String& path, int mode, const Value& value);
Expand Down Expand Up @@ -143,7 +145,6 @@ class Utility

private:
Utility();
static void CollectPaths(const String& path, std::vector<String>& paths);

#ifdef _WIN32
static int MksTemp (char *tmpl);
Expand Down
11 changes: 1 addition & 10 deletions lib/cli/apisetuputility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,16 +175,7 @@ bool ApiSetupUtility::SetupMasterApiUser()

fp.close();

#ifdef _WIN32
_unlink(apiUsersPath.CStr());
#endif /* _WIN32 */

if (rename(tempFilename.CStr(), apiUsersPath.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempFilename));
}
Utility::RenameFile(tempFilename, apiUsersPath);

return true;
}
Expand Down
34 changes: 3 additions & 31 deletions lib/cli/nodesetupcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,16 +207,7 @@ int NodeSetupCommand::SetupMaster(const boost::program_options::variables_map& v

fp.close();

#ifdef _WIN32
_unlink(apipath.CStr());
#endif /* _WIN32 */

if (rename(tempApiPath.CStr(), apipath.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempApiPath));
}
Utility::RenameFile(tempApiPath, apipath);

/* update constants.conf with NodeName = CN + TicketSalt = random value */
if (cn != Utility::GetFQDN()) {
Expand Down Expand Up @@ -472,17 +463,7 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,

fp.close();

#ifdef _WIN32
_unlink(apipath.CStr());
#endif /* _WIN32 */

if (rename(tempApiPath.CStr(), apipath.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempApiPath));
}

Utility::RenameFile(tempApiPath, apipath);

/* Generate zones configuration. */
Log(LogInformation, "cli", "Generating zone and object configuration.");
Expand Down Expand Up @@ -543,16 +524,7 @@ int NodeSetupCommand::SetupNode(const boost::program_options::variables_map& vm,

fp.close();

#ifdef _WIN32
_unlink(ticketPath.CStr());
#endif /* _WIN32 */

if (rename(tempTicketPath.CStr(), ticketPath.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempTicketPath));
}
Utility::RenameFile(tempTicketPath, ticketPath);
}

/* If no parent connection was made, the user must supply the ca.crt before restarting Icinga 2.*/
Expand Down
33 changes: 3 additions & 30 deletions lib/cli/nodeutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,16 +181,7 @@ bool NodeUtility::WriteNodeConfigObjects(const String& filename, const Array::Pt
fp << std::endl;
fp.close();

#ifdef _WIN32
_unlink(filename.CStr());
#endif /* _WIN32 */

if (rename(tempFilename.CStr(), filename.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(tempFilename));
}
Utility::RenameFile(tempFilename, filename);

return true;
}
Expand Down Expand Up @@ -360,16 +351,7 @@ bool NodeUtility::UpdateConfiguration(const String& value, bool include, bool re
ifp.close();
ofp.close();

#ifdef _WIN32
_unlink(configurationFile.CStr());
#endif /* _WIN32 */

if (rename(tempFile.CStr(), configurationFile.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(configurationFile));
}
Utility::RenameFile(tempFile, configurationFile);

return (found || include);
}
Expand Down Expand Up @@ -404,14 +386,5 @@ void NodeUtility::UpdateConstant(const String& name, const String& value)
ifp.close();
ofp.close();

#ifdef _WIN32
_unlink(constantsConfPath.CStr());
#endif /* _WIN32 */

if (rename(tempFile.CStr(), constantsConfPath.CStr()) < 0) {
BOOST_THROW_EXCEPTION(posix_error()
<< boost::errinfo_api_function("rename")
<< boost::errinfo_errno(errno)
<< boost::errinfo_file_name(constantsConfPath));
}
Utility::RenameFile(tempFile, constantsConfPath);
}
Loading

0 comments on commit 0438c86

Please sign in to comment.