@@ -132,7 +132,7 @@ uint32_t dol_file_size(const DOLHeader* dol) {
132132}
133133
134134void parse_until (
135- phosg::scoped_fd& fd ,
135+ FILE* f ,
136136 const FSTEntry* fst,
137137 const char * string_table,
138138 int start,
@@ -153,19 +153,11 @@ void parse_until(
153153 &string_table[fst[x].string_offset ()]);
154154
155155 pwd += sanitize_filename (&string_table[fst[x].file .dir_flag_string_offset & 0x00FFFFFF ]);
156- if (mkdir (pwd.c_str (), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) &&
157- (errno != EEXIST)) {
158- throw runtime_error (" cannot create directory " + pwd);
159- }
160- if (chdir (pwd.c_str ())) {
161- throw runtime_error (" cannot enter directory " + pwd);
162- }
163- parse_until (fd, fst, string_table, x + 1 , fst[x].dir .next_offset ,
164- base_offset, target_filenames);
156+ std::filesystem::create_directories (pwd);
157+ std::filesystem::current_path (pwd);
158+ parse_until (f, fst, string_table, x + 1 , fst[x].dir .next_offset , base_offset, target_filenames);
165159 pwd.resize (pwd_end);
166- if (chdir (pwd.c_str ())) {
167- throw runtime_error (" cannot return to directory " + pwd);
168- }
160+ std::filesystem::current_path (pwd.c_str ());
169161
170162 x = fst[x].dir .next_offset - 1 ;
171163
@@ -179,7 +171,8 @@ void parse_until(
179171 target_filenames.count (&string_table[fst[x].string_offset ()])) {
180172 string filename = sanitize_filename (&string_table[fst[x].string_offset ()]);
181173 try {
182- phosg::save_file (filename, preadx (fd, fst[x].file .file_size , fst[x].file .file_offset + base_offset));
174+ fseek (f, fst[x].file .file_offset + base_offset, SEEK_SET);
175+ phosg::save_file (filename, phosg::freadx (f, fst[x].file .file_size ));
183176 } catch (const exception& e) {
184177 phosg::fwrite_fmt (stderr, " !!! failed to write file: {}\n " , e.what ());
185178 }
@@ -220,10 +213,10 @@ int main(int argc, char* argv[]) {
220213 return -1 ;
221214 }
222215
223- phosg::scoped_fd fd (filename, O_RDONLY );
216+ auto f = phosg::fopen_unique (filename, " rb " );
224217
225218 ImageHeader header;
226- phosg::readx (fd , &header, sizeof (ImageHeader));
219+ phosg::freadx (f. get () , &header, sizeof (ImageHeader));
227220 if (format == Format::UNKNOWN) {
228221 if (header.gcm .gc_magic == 0xC2339F3D ) {
229222 format = Format::GCM;
@@ -261,29 +254,30 @@ int main(int argc, char* argv[]) {
261254 // if there are target filenames and default.dol isn't specified, don't
262255 // extract it
263256 if (target_filenames.empty () || target_filenames.count (" default.dol" )) {
264- string dol_data = phosg::preadx (fd, sizeof (DOLHeader ), dol_offset);
265- uint32_t dol_size = dol_file_size ( reinterpret_cast < const DOLHeader*>(
266- dol_data.data ()));
257+ fseek (f. get ( ), dol_offset, SEEK_SET );
258+ string dol_data = phosg::freadx (f. get (), sizeof (DOLHeader));
259+ uint32_t dol_size = dol_file_size ( reinterpret_cast < const DOLHeader*>( dol_data.data ()));
267260
268- dol_data += phosg::preadx (fd, dol_size - sizeof (DOLHeader),
269- dol_offset + sizeof (DOLHeader));
261+ dol_data += phosg::freadx (f.get (), dol_size - sizeof (DOLHeader));
270262
271263 phosg::save_file (" default.dol" , dol_data);
272264 }
273265
274266 if (target_filenames.empty () || target_filenames.count (" __gcm_header__.bin" )) {
275- phosg::save_file (" __gcm_header__.bin" , preadx (fd, 0x2440 , gcm_offset));
267+ fseek (f.get (), gcm_offset, SEEK_SET);
268+ phosg::save_file (" __gcm_header__.bin" , phosg::freadx (f.get (), 0x2440 ));
276269 }
277270
278271 if (target_filenames.empty () || target_filenames.count (" apploader.bin" )) {
279- string data = phosg::preadx (fd, sizeof (ApploaderHeader), gcm_offset + 0x2440 );
272+ fseek (f.get (), gcm_offset + 0x2440 , SEEK_SET);
273+ string data = phosg::freadx (f.get (), sizeof (ApploaderHeader));
280274 const auto * header = reinterpret_cast <const ApploaderHeader*>(data.data ());
281- data += phosg::preadx (
282- fd, header->size + header->trailer_size , gcm_offset + 0x2440 + sizeof (ApploaderHeader));
275+ data += phosg::freadx (f.get (), header->size + header->trailer_size );
283276 phosg::save_file (" apploader.bin" , data);
284277 }
285278
286- string fst_data = phosg::preadx (fd, fst_size, fst_offset);
279+ fseek (f.get (), fst_offset, SEEK_SET);
280+ string fst_data = phosg::freadx (f.get (), fst_size);
287281 const FSTEntry* fst = reinterpret_cast <const FSTEntry*>(fst_data.data ());
288282
289283 // if there are target filenames and fst.bin isn't specified, don't extract it
@@ -295,8 +289,7 @@ int main(int argc, char* argv[]) {
295289 phosg::fwrite_fmt (stderr, " > root: {:08X} files\n " , num_entries);
296290
297291 char * string_table = (char *)fst + (sizeof (FSTEntry) * num_entries);
298- parse_until (fd, fst, string_table, 1 , num_entries, base_offset,
299- target_filenames);
292+ parse_until (f.get (), fst, string_table, 1 , num_entries, base_offset, target_filenames);
300293
301294 return 0 ;
302295}
0 commit comments