| 401 | } |
| 402 | |
| 403 | void extractFile(const std::string& pattern) |
| 404 | { |
| 405 | for (const auto& i : directory) |
| 406 | { |
| 407 | const Dirent& dirent = *i.second; |
| 408 | if ((dirent.type == 0xf0) || (dirent.type == 0xe5)) |
| 409 | continue; |
| 410 | |
| 411 | if (fnmatch(pattern.c_str(), dirent.filename.c_str(), 0)) |
| 412 | continue; |
| 413 | |
| 414 | std::cout << fmt::format("Extracting '{}'\n", dirent.filename); |
| 415 | |
| 416 | std::ofstream outputFile(dirent.filename, |
| 417 | std::ios::out | std::ios::binary | std::ios::trunc); |
| 418 | if (!outputFile) |
| 419 | error("unable to open output file: {}", strerror(errno)); |
| 420 | |
| 421 | uint16_t sector = dirent.startSector; |
| 422 | while ((sector != 0) && (sector != 0xffff)) |
| 423 | { |
| 424 | uint8_t buffer[256]; |
| 425 | file.seekg((sector - 1) * 0x100, std::ifstream::beg); |
| 426 | if (!file.read((char*)buffer, sizeof(buffer))) |
| 427 | error("I/O error on read: {}", strerror(errno)); |
| 428 | if (!outputFile.write((const char*)buffer, sizeof(buffer))) |
| 429 | error("I/O error on write: {}", strerror(errno)); |
| 430 | |
| 431 | sector = allocationTable[sector]; |
| 432 | } |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | static void doCreate(int argc, const char* argv[]) |
| 437 | { |