zip_dir packs a directory tree into one file; unzip is the inverse. Both use * the same framing (CRC + path safety) as Checkpoint's wireless transfer, and * both stream through stdio — the bytes never enter the interpreter heap, so a * multi-megabyte save backup is fine. Return 0 on success, negative on error; * -2 specifically means the user cancelled with hold-B. Both drive the * innermost
| 439 | * -2 specifically means the user cancelled with hold-B. Both drive the |
| 440 | * innermost progress bar while they run. */ |
| 441 | void section_zip(void) |
| 442 | { |
| 443 | struct directory* dir; |
| 444 | char zipPath[PATHN]; |
| 445 | char outDir[PATHN]; |
| 446 | int res; |
| 447 | int i; |
| 448 | |
| 449 | gui_status("Zip demo"); |
| 450 | |
| 451 | if (!sd_exists(g_scratch)) { |
| 452 | gui_message("Run the SD card section first — it creates the files to zip."); |
| 453 | return; |
| 454 | } |
| 455 | |
| 456 | sprintf(zipPath, "%s/demo.zip", g_scratch); |
| 457 | sprintf(outDir, "%s/unpacked", g_scratch); |
| 458 | |
| 459 | progress_note("zipping"); |
| 460 | res = zip_dir(g_scratch, zipPath); |
| 461 | printf("zip_dir: %d\n", res); |
| 462 | if (res != 0) { |
| 463 | progress_clear(); |
| 464 | gui_message(res == -2 ? "Zip cancelled." : "zip_dir failed, see the log."); |
| 465 | return; |
| 466 | } |
| 467 | |
| 468 | if (sd_mkdirs(outDir) != 0) { |
| 469 | progress_clear(); |
| 470 | gui_message("Could not create the unzip target."); |
| 471 | return; |
| 472 | } |
| 473 | |
| 474 | progress_note("unzipping"); |
| 475 | res = unzip(zipPath, outDir); |
| 476 | printf("unzip: %d\n", res); |
| 477 | progress_clear(); |
| 478 | if (res != 0) { |
| 479 | gui_message(res == -2 ? "Unzip cancelled." : "unzip failed, see the log."); |
| 480 | return; |
| 481 | } |
| 482 | |
| 483 | dir = read_directory(outDir); |
| 484 | if (dir != NULL) { |
| 485 | printf("unpacked %d entries:\n", dir->count); |
| 486 | for (i = 0; i < dir->count; i++) { |
| 487 | printf(" %s\n", dir->files[i]); |
| 488 | } |
| 489 | delete_directory(dir); |
| 490 | } |
| 491 | gui_message("Zip round trip finished."); |
| 492 | |
| 493 | /* Tidy up the archive; the scratch files stay for the other sections. */ |
| 494 | remove(zipPath); |
| 495 | } |
| 496 | |
| 497 | /* ------------------------------------------------------------------------- */ |
| 498 | /* 7. Save data: file-level access to a title's save archive */ |