87 , fs::path
const& path_file_self)
90 ns_env::set(
"FIM_BIN_SELF", path_file_self, ns_env::Replace::Y);
96 auto const dir = path.dir;
97 auto const bin = path.bin;
99 Try(fs::create_directories(dir.global));
100 Try(fs::create_directories(dir.app));
101 Try(fs::create_directories(dir.app_bin));
102 Try(fs::create_directories(dir.app_sbin));
103 Try(fs::create_directories(dir.instance));
105 uint64_t offset_beg = 0;
117 auto f_write_from_header = [&](fs::path path_file, uint64_t offset_end)
118 ->
Value<std::pair<uint64_t,uint64_t>>
121 offset_beg = offset_end;
124 if ( ! Try(fs::exists(path_file)) )
133 Try(fs::permissions(path_file.c_str(), fs::perms::owner_all | fs::perms::group_all));
135 return std::make_pair(offset_beg, offset_end);
149 auto f_write_from_offset = [&](std::ifstream& file_binary, fs::path path_file, uint64_t offset_end)
150 ->
Value<std::pair<uint64_t,uint64_t>>
153 uint64_t offset_beg = offset_end;
154 logger(
"D::Writting binary file '{}'", path_file);
156 file_binary.seekg(offset_beg);
159 return_if(not file_binary.read(
reinterpret_cast<char*
>(&size),
sizeof(size)), Error(
"E::Could not read binary size"));
161 if (fs::exists(path_file, ec))
163 file_binary.seekg(offset_beg + size +
sizeof(size));
168 std::vector<char> buffer(size);
169 return_if(not file_binary.read(buffer.data(), size), Error(
"E::Could not read binary"));
171 std::ofstream of{path_file, std::ios::out | std::ios::binary};
172 return_if(not of.is_open(), Error(
"E::Could not open output file '{}'", path_file));
174 return_if(not of.write(buffer.data(), size), Error(
"E::Could not write binary file '{}'", path_file));
176 fs::permissions(path_file, fs::perms::owner_all | fs::perms::group_all, ec);
177 log_if(ec,
"E::Error on setting permissions of file '{}': {}", path_file.string(), ec.message());
180 return std::make_pair(offset_beg, file_binary.tellg());
184 auto start = std::chrono::high_resolution_clock::now();
185 std::ifstream file_binary{bin.self, std::ios::in | std::ios::binary};
186 return_if(not file_binary.is_open(), Error(
"E::Could not open flatimage binary file"));
187 constexpr static char const str_raw_json[] =
189 #embed FIM_FILE_TOOLS
191 std::tie(offset_beg, offset_end) = Pop(f_write_from_header(dir.app_bin /
"fim_boot" , 0));
193 for(
auto&& tool : Pop(Pop(
ns_db::from_string(str_raw_json)).
template value<std::vector<std::string>>()))
195 std::tie(offset_beg, offset_end) = Pop(f_write_from_offset(file_binary, dir.app_bin / tool, offset_end));
198 auto f_symlink = [](
auto&& points_to,
auto&& saved_at)
200 if(fs::exists(saved_at)) { fs::remove(saved_at); }
201 fs::create_symlink(points_to, saved_at);
204 fs::path path_file_dwarfs_aio = dir.app_bin /
"dwarfs_aio";
205 Try(f_symlink(path_file_dwarfs_aio, dir.app_bin /
"dwarfs"));
206 Try(f_symlink(path_file_dwarfs_aio, dir.app_bin /
"mkdwarfs"));
207 auto end = std::chrono::high_resolution_clock::now();
210 for(
auto const& busybox_applet : arr_busybox_applet)
212 Try(f_symlink(dir.app_bin /
"busybox", dir.app_sbin / busybox_applet));
216 ns_env::set(
"FIM_OFFSET", std::to_string(offset_end).c_str(), ns_env::Replace::Y);
217 return_if(offset_end != offset, Error(
"E::Broken image actual offset({}) != offset({})", offset_end, offset));
218 logger(
"D::FIM_OFFSET: {}", offset_end);
221 if( getenv(
"FIM_MAIN_OFFSET") ){ std::println(
"{}", offset_end); exit(0); }
224 if ( getenv(
"FIM_DEBUG") !=
nullptr )
226 auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
227 logger(
"D::Copy binaries finished in '{}' ms", elapsed.count());
231 int code = execve(std::format(
"{}/fim_boot", dir.app_bin.string()).c_str(), argv, environ);
232 return Error(
"E::Could not perform 'evecve({})': {}", code, strerror(errno));