From 1740a0d4556af37c8a182a6fbc396e20470088d7 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Tue, 12 May 2020 01:50:18 -0400 Subject: miragextract: detect hybrid iso/mac data tracks --- miragextract.c | 49 ++++++++++++++++++++++++++++++++++++------------- miragextract.rst | 56 +++++++++++++++++++++++++++++--------------------------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/miragextract.c b/miragextract.c index 02325ae..d9b4832 100644 --- a/miragextract.c +++ b/miragextract.c @@ -93,6 +93,36 @@ char *human_mb(int bytes) { return buf; } +const char *get_data_extension(MirageTrack *track) { + MirageSector *sector; + const char *ext = "iso"; + int sec; + gint len; + const guint8 *buf; + + /* examine first sector, see if it's got Apple magic */ + sec = mirage_track_get_track_start(track); + + if(!(sector = mirage_track_get_sector(track, sec, 0, &gerr))) + die(NULL); + + if(!(mirage_sector_get_data(sector, &buf, &len, &gerr))) + die(NULL); + + if(buf[0] == 'E' && buf[1] == 'R' && buf[3] == 0 && (buf[2] == 0x02 || buf[2] == 0x08)) + { + ext = "hfs"; + /* if it also has ISO9660 magic, it's a hybrid */ + if((sector = mirage_track_get_sector(track, sec + 16, 0, NULL)) && + mirage_sector_get_data(sector, &buf, &len, NULL) && + (memcmp("\x01" "CD001", buf, 6) == 0)) + ext = "hfs.iso"; + } + + return ext; +} + + /* list and (optionally) extract a track. this should be broken up into smaller functions for clarity. */ void process_track(int t, int extract) { @@ -101,7 +131,7 @@ void process_track(int t, int extract) { int sector_type, sec = 0; gint len; const guint8 *buf; - char *ext; + const char *ext; char outfile[PATH_MAX + 1]; FILE *out = NULL; SNDFILE *sfout = NULL; @@ -118,8 +148,8 @@ void process_track(int t, int extract) { switch(sector_type) { case MIRAGE_SECTOR_MODE1: case MIRAGE_SECTOR_MODE2_FORM1: - printf("data: "); - ext = "iso"; + ext = get_data_extension(track); + printf("data(%s): ", ext); if(!want_data) extract = 0; break; case MIRAGE_SECTOR_AUDIO: @@ -134,15 +164,6 @@ void process_track(int t, int extract) { break; } - /* examine first sector, see if it's got Apple magic */ - sec = mirage_track_get_track_start(track); - if(!(sector = mirage_track_get_sector(track, sec, 0, &gerr))) - die(NULL); - if(!(mirage_sector_get_data(sector, &buf, &len, &gerr))) - die(NULL); - if(buf[0] == 'E' && buf[1] == 'R' && buf[3] == 0 && (buf[2] == 0x02 || buf[2] == 0x08)) - ext = "dmg"; - sprintf(outfile, "%s%02d.%s", outfilebase, output_track_number, ext); if(extract) { @@ -176,6 +197,7 @@ void process_track(int t, int extract) { } } + sec = mirage_track_get_track_start(track); while((sector = mirage_track_get_sector(track, sec++, 0, NULL))) { if(!(mirage_sector_get_data(sector, &buf, &len, &gerr))) die(NULL); @@ -197,7 +219,8 @@ void process_track(int t, int extract) { if(sfout) sf_close(sfout); if(out) fclose(out); - printf("%d bytes (%sMB, %d sectors)\n", bytes, human_mb(bytes), sec); + // printf("%d bytes (%sMB, %d sectors)\n", bytes, human_mb(bytes), sec); + printf("%d bytes (%sMB)\n", bytes, human_mb(bytes)); if(extract) printf(" Extracted to %s\n", outfile); total_bytes += bytes; diff --git a/miragextract.rst b/miragextract.rst index 9ac2048..fef2611 100644 --- a/miragextract.rst +++ b/miragextract.rst @@ -39,40 +39,41 @@ OPTIONS --help Print short usage string. --a Extract only audio tracks. Default is to extract all tracks. +-a Extract only audio tracks. Default is to extract all tracks. --b Sets the base filename for the output files. Default is 'track'. - Can be prefixed with a directory to write files in that dir, - but the dir must already exist (example: -b extracted/track). See - also the -n option. +-b Sets the base filename for the output files. Default is **track**. + Can be prefixed with a directory to write files in that dir, + but the dir must already exist (example: -b extracted/track). See + also the -n option. --d Extract only data tracks. Default is to extract all tracks. +-d Extract only data tracks. Default is to extract all tracks. --f Sets the format and filename extension for the output audio files. - Choices are **wav**, **ogg**, **flac**, **cdda** (raw CD audio). Default is **wav**. +-f Sets the format and filename extension for the output audio files. + Choices are **wav**, **ogg**, **flac**, **cdda** (raw CD audio). + Default is **wav**. --l Lists the tracks in the image without extracting them. +-l Lists the tracks in the image without extracting them. --n Set the base filename to the input filename, minus its extension. - E.g. for foo.cue, this is the same as saying "-b foo". Beware of - using input filenames with directory separators in them: the output files - will be written in the same dir as the input file. Hopefully you - have permission to write there. +-n Set the base filename to the input filename, minus its extension. + E.g. for foo.cue, this is the same as saying "-b foo". Beware of + using input filenames with directory separators in them: the output files + will be written in the same dir as the input file. Hopefully you + have permission to write there. --p Password for encrypted images. Note that anyone who can run **ps(1)** - on your system may be able to view the password. Also note that password - support in miragextract is *completely* untested: I have no - encrypted images to test with. +-p Password for encrypted images. Note that anyone who can run **ps(1)** + on your system may be able to view the password. Also note that password + support in miragextract is *completely* untested: I have no + encrypted images to test with. --q Quality setting for ogg and flac output files. Integer from 0 - to 10. Default is 7. Has very little effect on flac, and no effect on - wav or cdda output. +-q Quality setting for ogg and flac output files. Integer from 0 + to 10. Default is 7. Has very little effect on flac, and no effect on + wav or cdda output. --s Swaps bytes in audio tracks. Use this if your audio files sound - like white noise or gibberish. +-s Swaps bytes in audio tracks. Use this if your audio files sound + like white noise or gibberish. --t Takes a track number (1-99), and extracts only that one track. - Default behaviour is to extract all tracks. +-t Takes a track number (1-99), and extracts only that one track. + Default behaviour is to extract all tracks. Always include a space between an option and its argument (e.g. **-b foo**, not **-bfoo**). @@ -90,8 +91,9 @@ match the encoding set with -f. Note that mp3 is NOT a valid -f option. If you need mp3, extract to .wav and then use a tool like lame or ffmpeg to convert to mp3. -Output data tracks will be named to end in '.iso', or '.dmg' if they look -like Apple disk images. +Output data tracks will be named to end in '.iso' by default, or '.hfs' +if they look like Apple disk images, or '.hfs.iso' for "hybrid" images +that can be mounted as either (such as Blizzard's Mac/PC releases). Images with multiple sessions should be supported, but have not been tested. Track numbering just continues, so a disc with 2 sessions of -- cgit v1.2.3