18#include <boost/algorithm/string.hpp>
23#include <ext_data_clnt.hh>
27namespace fs = std::filesystem;
28namespace bp = boost::process;
31 bool Check_exist(std::string_view exe)
33 auto exe_path = fs::path{ exe };
34 return fs::exists(exe_path) || fs::is_symlink(exe_path);
39 void Append_elements(std::vector<T>& base, std::vector<T> to_append)
41 base.reserve(base.size() + to_append.size());
42 for (
auto& ele : to_append)
44 base.emplace_back(std::move(ele));
48 void Append_lmds(std::vector<std::string>& lmds, std::string_view filename_regex)
58 auto option_regex = std::regex{
"^--[0-9A-z,=\\-]+" };
59 auto lmd_regex = std::regex{
"^.*\\.lmd$" };
61 for (
auto& split_item : splits)
63 if (std::regex_match(split_item, option_regex))
65 result.options.emplace_back(std::move(split_item));
67 else if (std::regex_match(split_item, lmd_regex))
69 Append_lmds(result.lmds, split_item);
71 else if (Check_exist(split_item))
74 if (not result.executable.empty())
76 R3BLOG(info, fmt::format(
"Ucesb Executable has been set to \"{}\" ", result.executable));
77 R3BLOG(error, fmt::format(
"Found another executable \"{}\" but only one is allowed!", split_item));
80 R3BLOG(info, fmt::format(
"Ucesb Executable is set to \"{}\" ", split_item));
81 result.executable = std::move(split_item);
86 result.others.emplace_back(std::move(split_item));
92 void lmd_filenames_sorting(std::vector<std::string>& filenames)
95 std::sort(filenames.begin(), filenames.end());
104 R3BLOG(debug, fmt::format(
"Resolving string command: {}", cmd));
106 auto splits = std::vector<std::string>{};
107 boost::split(splits, cmd, boost::is_any_of(
" "), boost::token_compress_on);
112 auto results = parse_splits(std::move(splits));
113 lmd_filenames_sorting(results.lmds);
123 launch_strings_ = resolve_exe_options_lmd(command_string);
124 if (launch_strings_.executable.empty())
126 R3BLOG(error, fmt::format(
"An unpacker executable doesn't exist in options {:?}", command_string));
128 Append_elements(launch_args, std::move(launch_strings_.options));
129 Append_elements(launch_args, std::move(launch_strings_.lmds));
130 Append_elements(launch_args, std::move(launch_strings_.others));
133 fmt::format(
"Ucesb command after resolving wildcard filename: \n {} {}",
134 launch_strings_.executable,
135 fmt::join(launch_args,
" ")));
140 server_pipe_ = boost::process::async_pipe{ ios_ };
141 ucesb_server_ = std::make_unique<boost::process::child>(
142 launch_strings_.executable, boost::process::args(launch_args), boost::process::std_out > server_pipe_);
143 R3BLOG(info, fmt::format(
"Launching an ucesb server with pid: {}", ucesb_server_->id()));
144 if (
auto is_status_ok = client_->connect(server_pipe_.native_source()); not is_status_ok)
146 R3BLOG(error,
"ext_data_clnt::connect() failed");
147 const auto* msg = (client_->last_error() ==
nullptr) ?
UCESB_NULL_STR_MSG : client_->last_error();
156 if (
auto ret_val = client_->close(); ret_val != 0)
158 R3BLOG(error,
"ext_data_clnt::close() failed");
160 auto err_code = std::error_code{};
161 auto boost_err = boost::system::error_code{};
163 server_pipe_.close(boost_err);
164 R3BLOG(info, fmt::format(
"pipe closed: {}", boost_err.what()));
168 R3BLOG(warn, fmt::format(
"Failed to close Ucesb server! Error code: {}", err_code.value()));
169 ucesb_server_->terminate(err_code);
170 R3BLOG(warn,
"Killing Ucesb server");
174 R3BLOG(info,
"Ucesb server is closed successfully");
177 auto child_handle = bp::child::child_handle{ ucesb_server_->id() };
178 R3BLOG(warn, fmt::format(
"Trying to killing Ucesb server with pid: {}", child_handle.id()));
179 bp::detail::api::terminate(child_handle, err_code);
182 R3BLOG(info, fmt::format(
"Killed: {}", err_code));
#define R3BLOG(severity, x)
constexpr auto CHILD_CLOSE_WAITING_TIME
constexpr auto UCESB_NULL_STR_MSG
void SetLaunchCmd(const std::string &command_string)
auto GetFilesFromRegex(std::string_view filename_regex) -> std::vector< std::string >