Looking for Computer Science & Information Technology online
courses ?
Check my new web site: https://www.yesik.it !
Il y a peu de temps, j'ai eu besoin de récupérer sous Linux des données enregistrées dans une image disque MacOS X (fichier .dmg).
Pour la petite histoire, il s'agissait de l'archive de JavaFX qui comme vous le savez peut-être n'est disponible dans sa version 1.1 que pour Windows et Mac OS X. Mais les informations données ici devraient pouvoir s'appliquer à n'importe quelle image disque ".dmg".
Sommaire
Ce qui ne marche pas
Comme il se doit, j'ai tout d'abord commencé par une rapide recherche sur internet. Où j'ai trouvé à l'adresse http://www.weiqigao.com/blog/2008/12/04/using_javafx_1_0_on_linux.html la procédure suivante. Celle-ci consiste à décompresser l'archive, puis à monter l'image disque décompressée.
sh$ bunzip2 javafx_sdk-1_1_1-macosx-universal.dmg bunzip2: Can't guess original name for javafx_sdk-1_1_1-macosx-universal.dmg -- using javafx_sdk-1_1_1-macosx-universal.dmg.out bunzip2: javafx_sdk-1_1_1-macosx-universal.dmg: trailing garbage after EOF ignored sh$ mkdir mount-point sh$ sudo mount -o loop -t hfsplus javafx_sdk-1_1_1-macosx-universal.dmg.out mount-point Password: mount: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so
Oups! D'après son Blog, Gao a réussi à monter son image ainsi sur Ubuntu. Mais visiblement sur ma distribution Debian Etch, ça ne marche pas. Dommage...
Investigations
La question à se poser maintenant, est "est-ce que le fichier décompressé contient bien une image disque d'un système de fichier HFS+"?

HFS+
HFS+ est le système de fichiers utilisé par Mac OS X. Les anciens Mac (pré-OS X) utilisaient le système de fichier HFS.
Plusieurs solutions pour répondre à cette question. Pour ma part, j'aime bien utiliser hexdump. C'est un peu "rustique" mais ça permet d'avoir une première idée du contenu d'un fichier "mystère":
sh$ hexdump -C javafx_sdk-1_1_1-macosx-universal.dmg.out | more
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fe |................|
000001c0 ff ff ee fe ff ff 01 00 00 00 ff ff 03 00 00 00 |................|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200 45 46 49 20 50 41 52 54 00 00 01 00 5c 00 00 00 |EFI PART....\...|
00000210 17 1b d9 7e 00 00 00 00 01 00 00 00 00 00 00 00 |...~............|
00000220 ff ff 03 00 00 00 00 00 22 00 00 00 00 00 00 00 |........".......|
00000230 de ff 03 00 00 00 00 00 61 45 5a dc 09 f7 47 48 |........aEZ...GH|
00000240 aa 88 bb bf 04 20 fe cd 02 00 00 00 00 00 00 00 |..... ..........|
00000250 80 00 00 00 80 00 00 00 c3 ef fc 93 00 00 00 00 |................|
00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000400 00 53 46 48 00 00 aa 11 aa 11 00 30 65 43 ec ac |.SFH.......0eC..|
00000410 8d 5c 6f b3 57 8e 78 45 a7 f6 56 eb ad e2 b6 5e |.\o.W.xE..V....^|
00000420 28 00 00 00 00 00 00 00 d7 ff 03 00 00 00 00 00 |(...............|
00000430 00 00 00 00 00 00 00 00 64 00 69 00 73 00 6b 00 |........d.i.s.k.|
00000440 20 00 69 00 6d 00 61 00 67 00 65 00 00 00 00 00 | .i.m.a.g.e.....|
00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00004800 48 2b 00 04 00 00 01 00 31 30 2e 30 00 00 00 00 |H+......10.0....|
Ha, ha! A l'offset 4800(hex) je vois les deux caractères H+. Et alors? Et bien, il s'agit de la signature dans l'en-tête d'un système de fichier HFS+. Si un tel système de fichier est dans l'archive, son en-tête est situé à l'offset 4800(hex).
Bon, ben il n'y a plus qu'à monter l'image en "sautant" les 4800 premiers octets. Oui?
sh$ sudo losetup -o 18432 -s -f javafx_sdk-1_1_1-macosx-universal.dmg.out /dev/loop0 sh$ sudo mount -o loop -t hfsplus /dev/loop0 mount-point mount: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so
Ah ben non... Pourtant j'utilise losetup pour créer un pseudo-device correspondant au fichier. Et je précise bien de "sauter" 18432(dec) octets. Ce qui correspond bien à l'offset 4800(hex).
L'explication de ce problème se trouve en lisant (mieux) la documentation du format HFS+ (TN1150: HFS+ Volume Format). Plus particulièrement la section sur l'en-tête HFS+:
Each HFS Plus volume contains a volume header 1024 bytes from the start of the volume.
Et oui: l'en-tête HFS+ n'est pas au début du volume, mais 1024 octects plus loin. Bref, j'ai "sauté" 1024 octets de trop:
sh$ sudo losetup -d /dev/loop0 # On annule les bêtises faites précédemment sh$ sudo sudo losetup -o 17408 /dev/loop0 javafx_sdk-1_1_1-macosx-universal.dmg.out # 18432-1024 sh$ sudo mount -o loop -t hfsplus /dev/loop0 mount-point sh$ ls mount-point background.png JavaFX 1.1 SDK.mpkg
Et voilà! L'image disque du fichier .dmg est montée sur ma machine Linux. Super! Enfin, sauf que les fichiers qui m'intéressent sont dans un paquet MacOS X (le dossier .mpkg que l'on voit dans le résultat de la commande ls). Bon ben ça n'est pas tout de suite que je vais jouer avec JavaFX...
Extraire sous Linux les données d'un méta-package Mac OS X
Si comme moi vous n'avez pas de chance, et que les données que vous souhaitez récupérer sur votre machine Linux sont encapsulées dans un méta-package (dossier .mpkg), vous pouvez peut-être vous en tirer avec la procédure suivante.
Tout d'abord, il faut explorer le contenu du dossier .mpkg à la recherche d'une archive contenant effectivement les données qui vous intéressent. C'est une archive GZip. Un find devrait faire l'affaire:
sh$ ls mount-point
background.png JavaFX 1.1 SDK.mpkg
sh$ find 'mount-point/JavaFX 1.1 SDK.mpkg' -name '*.gz'
mount-point/JavaFX 1.1 SDK.mpkg/Contents/Packages/javafxsdk.pkg/Contents/Archive.pax.gz
Un seul '.gz' dans le package. Là je n'ai pas le choix. Les données qui m'intéressent sont forcément là-dedans. Hop: copie, décompression.
sh$ mkdir extract sh$ cp 'mount-point/JavaFX 1.1 SDK.mpkg/Contents/Packages/javafxsdk.pkg/Contents/Archive.pax.gz' extract sh$ cd extract sh$ gunzip Archive.pax.gz sh$ ls Archive.pax
Reste à savoir ce qu'est ce fichier ".pax". La commande file vient à notre rescousse:
sh$ file Archive.pax Archive.pax: ASCII cpio archive (pre-SVR4 or odc)
D'accord: c'est une archive cpio. Maintenant, c'est facile:
sh$ cpio -id < Archive.pax 90696 blocks sh$ ls Archive.pax lib samples timestamp bin LICENSE.txt servicetag COPYRIGHT.html profiles src.zip docs README.html THIRDPARTYLICENSEREADME.txt sh$ find . -name javafxc ./bin/javafxc
Enfin: j'ai récupéré le SDK JavaFX. Ca a été un peu laborieux, mais finalement c'est fait. Je vais enfin pouvoir essayer JavaFX. Mais ceci est une autre histoire...