| 246 | } |
| 247 | |
| 248 | void CheckUnsquashfs() { |
| 249 | const std::array<const char*, 3> ExecveArgs = { |
| 250 | "unsquashfs", |
| 251 | "--help", |
| 252 | nullptr, |
| 253 | }; |
| 254 | |
| 255 | int fd = ::syscall(SYS_memfd_create, "stdout", 0); |
| 256 | int32_t Result = Exec::ExecAndWaitForResponseRedirect(ExecveArgs[0], const_cast<char* const*>(ExecveArgs.data()), fd, fd); |
| 257 | Has_Unsquashfs = Result != -1; |
| 258 | if (Has_Unsquashfs) { |
| 259 | // Seek back to the start |
| 260 | lseek(fd, 0, SEEK_SET); |
| 261 | |
| 262 | // Unsquashfs needs to support zstd |
| 263 | // Scan its output to find the zstd compressor |
| 264 | FILE* fp = fdopen(fd, "r"); |
| 265 | char* Line {nullptr}; |
| 266 | size_t Len; |
| 267 | |
| 268 | bool ReadingDecompressors = false; |
| 269 | bool SupportsZSTD = false; |
| 270 | while (getline(&Line, &Len, fp) != -1) { |
| 271 | if (!ReadingDecompressors) { |
| 272 | if (strstr(Line, "Decompressors available")) { |
| 273 | ReadingDecompressors = true; |
| 274 | } |
| 275 | } else { |
| 276 | if (strstr(Line, "zstd")) { |
| 277 | SupportsZSTD = true; |
| 278 | } |
| 279 | } |
| 280 | } |
| 281 | |
| 282 | free(Line); |
| 283 | fclose(fp); |
| 284 | |
| 285 | // Disable unsquashfs if it doesn't support ZSTD |
| 286 | if (!SupportsZSTD) { |
| 287 | Has_Unsquashfs = false; |
| 288 | } |
| 289 | } |
| 290 | close(fd); |
| 291 | } |
| 292 | void CheckZenity() { |
| 293 | // Check if zenity exists on the host |
| 294 | std::array<const char*, 3> ExecveArgs = { |