Zottels Zeug
  zuletzt bearbeitet: Tue, 22 Mar 2016 02:42:06 +0100  
As this is a post intended for a worldwide audience, I'll write it in English, not in German like the rest of my blog.

So my 2008 iMac broke down last weekend, and this was the time to get rid of the last piece of Apple hardware in my household and return back to Linux.
I had backups, of course, done with Time Machine. "No problem!" I thought. I had looked at the files in OS X often and thought it was just a matter of copying back the files from the latest backup to Linux after mounting the HD. I thought wrong.
When I browsed through the files, I found that in many cases, where there should have been directories, I only found files with a size of 0 bytes instead. Huh? What's going on?

Hard links for directories
Some searching on the net revealed this hint from the former macosxhints site (which was always excellent!) that nowadays belongs to Macworld.
Bottom line: HFS+ supports hard links for directories, but this is unsupported under Linux.
But boy, what do they do with those hard-linked directories?! It's really absolutely ridiculous.
In the root directory of the disk, there is a directory called ".HFS+ Private Directory Data\r". And yes, that's a carriage return at the end of this directory name. You'll never see this directory on a Mac, it's hidden even if you choose to see hidden files. It contains large numbers of directories, all named dir_xxx, where xxx is a number.
Now, if you do an ls -l on a directory where directories have mysteriously turned into files, you'll see something like this:
drwxr-xr-x        1  503      503  26 23. Jun 2012  nicole
-r--r--r-- 17909650 root 20523400   0 28. Aug 2010  rozottel
-r--r--r-- 19911125 root 20523401   0 28. Aug 2010  Shared
drwxr-xr-x        1  501      501 114 18. Dez 02:22 zottel

rozottel and Shared should be directories, they aren't. But the number you see after the permission is the number of dir_xxx you'll find at the ".HFS+ Private Directory Data\r" directory. Example: The contents of rozottel above can be found in ".HFS+ Private Directory Data^M/dir_17909650". Of course, subdirectories there can contain other directories crippled in the same way.
Gah! Trying to restore even a few directories manually would take ages!

A script to solve the problem
So I wrote a short Perl script to solve the problem.
BTW, that number from above is actually a number that would normally represent the number of hard links that point to the file. It doesn't make sense at all to use this value for names in this private directory, and so, of course, it doesn't mean what it should mean. I'm not sure if this is Linux not supporting all aspects of HFS+ or Apple abusing the specs of that file system in completely braindead ways, but either way, I'm not sure if such a Time Machine backup would survive a file system check with repair under Linux, so better not try that. (The same probably happens with other HFS+ disks where someone has used hard links for directories, but as nobody in their right mind normally does that, it's only a problem for Time Machine backup media.)
The script takes a directory on the Time Machine file system as first parameter, and a directory where you want to copy the backup directory to as second parameter.
Side note: It assumes that your current working directory is a directory on the backup disk. It won't work if you are somewhere else and use absolute paths.
time_machine.pl foo/ /home/bar/
In this example, foo/ will be created under /home/bar/, and all the contents of foo/ will be recursively copied.
If you omit the second parameter, time_machine.pl will just traverse all files in all subdirectories and show you the complete size of what would be copied. (I needed this because, of course, a simple du won't work on such structures.)
Files that already exist at the destination are not overwritten. Thus, you can cancel the job by pressing Ctrl-C and resume later. Just be sure to delete the last file the script was working on (it shows them all on the console) at the destination after pressing Ctrl-C, because it has probably not been copied completely.
You'll find time_machine.pl as an attachment to this post (click on the paper clip at the end of this post).
It's by no means done well or sophisticatedly, it's just a quick hack I did to solve the problem for myself. Edit it to your needs if you want it to do something else.
And, of course, use it at your own risk.