From 66c81754230db6bf4b6a98585f0712ae84bd45cb Mon Sep 17 00:00:00 2001 From: Nicholas O'Connor Date: Wed, 15 May 2019 18:03:15 -0700 Subject: [PATCH] translates windows drive letters to canonical paths --- CMakeLists.txt | 2 +- include/paths.hpp | 1 + src/paths/drive_letters.cpp | 51 +++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 src/paths/drive_letters.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 38ca889..0fec1b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,7 @@ include_directories("${CMAKE_CURRENT_BINARY_DIR}/include") set(src "${CMAKE_SOURCE_DIR}/src") lava_create_gutlib( - SUBDIRS bottles config launch + SUBDIRS bottles config launch paths DEPENDS cog) lava_create_executable(TARGET cellar diff --git a/include/paths.hpp b/include/paths.hpp index 2eb1e3d..582700f 100644 --- a/include/paths.hpp +++ b/include/paths.hpp @@ -5,5 +5,6 @@ namespace cellar { namespace paths { extern std::string translate(std::string in_path, bool lazy = false); + extern std::string resolve_drive_letter(std::string in_path); } } diff --git a/src/paths/drive_letters.cpp b/src/paths/drive_letters.cpp new file mode 100644 index 0000000..452d22d --- /dev/null +++ b/src/paths/drive_letters.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +#include + +#include "bottles.hpp" +#include "output.hpp" +#include "paths.hpp" + +using namespace std; + +string cellar::paths::resolve_drive_letter(string in_path) { + bool windows_input; + static regex drive_letter_rgx(R"([a-zA-Z]:\\)"); + + windows_input = regex_match(in_path.substr(0, 3), drive_letter_rgx); + + string out_path = ""; + + if (windows_input) { + string drive_letter = boost::algorithm::to_lower_copy(in_path.substr(0, 2)); + + string link_path = ""; + link_path.append(bottles::active_bottle.canonical_path); + link_path.append("/dosdevices/"); + link_path.append(drive_letter); + + char stringbuffer[512]; + ssize_t bufflen = readlink(link_path.c_str(), stringbuffer, sizeof(stringbuffer) - 1); + + if (bufflen != -1) { + stringbuffer[bufflen] = '\0'; + out_path.append(stringbuffer); + } else { + throw runtime_error("readlink isn't having it"); + } + + string rest_of_path = in_path.substr(3, in_path.size() - 2); + size_t slashpos = rest_of_path.find("\\"); + while (slashpos != std::string::npos) { + rest_of_path.replace(0, 1, "/"); + slashpos = rest_of_path.find("\\"); + } + + out_path.append(rest_of_path); + } + + return out_path; +}