Easily create HFS-aware PKZIP and unix archives

Nov 26, '03 11:06:00AM

Contributed by: SOX

HFS files have meta-data and resource forks that are lost during common unix archive operations like cpio, tar, gzip. Panther's new archive maker is HFS aware, but it's not compatible with Stuffit or tar and zip. Fortunately you can use ditto to make both PKZIP (Windows) and compressed Unix archives that preserve the resource forks! There are three types of archives you can produce: pkzip, cpio-zipped, and tar-zipped. The first two are easy. The latter is tricky to create and to undo, so I dont reccomend it but the method is instructuve so I'll describe it anyhow.

To create a pkzip archive of "some_folder" type:

 % ditto -c -k -X --rsrc some_folder  some_folder.zip
Alternatively, to create a compressed cpio archive type:
 % ditto -c -X  -z --rsrc some_folder some_folder.cpio
By the way, although most people are more familiar with tar-zip, a cpio archive is a univerally compatible unix archive, and if anything, is more versatile (see man pages for cpio and pax for info). If you send this file to a unix or Windows person, they can open these using cpio and pkzip, respectively. For example, on any unix machine (besides OS X), to open a cpio archive type:
 % cpio -i -I -z some_folder.cpio 
and it will unarchive it in the current folder. In this folder you may now observe that for each file some_file that has meta-data, there will be an associated file named ._somefile which contains all the meta-data and resource forks. This is called AppleDouble format. Note that not all files have meta-data, so you may not see this AppleDouble format file for every regular HFS file.

On an OS X machine, you can extract the archive using cpio also, and you will see these same AppleDouble files. However, when you do this on an HFS file system, it fails to restore the resource forks to the right files. Therefore, don't use cpio to unarchive on an HFS file system. It does restore the resource forks on Mac OS if you have a UFS partition or a mounted NFS drive, however. On an HFS system, you recover the resource forks from the cpio archive using ditto again:

 % ditto -x --rsrc some_folder.cpio some_folder_destination
To recover the resource forks on a pkzipped file, you have to use StuffIt Expander. Strangely, ditto does not work in this case -- I'm guessing this is a bug, since it should work.

ADVANCED STUFF
You don't really need to read further, but you might be interested is seeing how to use these tricks to make a tar gzip archive that has resource forks! Well it's not pretty and it's hard to undo. But in case you want to, here is a script. Save the following into a file called tar_hfs.sh and make it executable (chmod a+x tar_hrs.sh).


#!/bin/bash

 TEMPDIR=`mktemp -d`  || exit 1
 TEMPFIFO=`mktemp -p $TEMPDIR`  &&  mkdir ${TEMPDIR}/$1 && {

   ditto --rsrc -c -X $1 $TEMPFIFO  
   ditto -x $TEMPFIFO ${TEMPDIR}/$1

   (cd $TEMPDIR && tar -cz  $1)
}

rm -fr $TEMPDIR
To use this on some_folder, type tar_hfs.sh some_folder > some_folder.tgz. Again, this saves the meta-data in AppleDouble format. I use ditto to first create a cpio archive then I use ditto to unpack it in a resource-unaware manner, leaving the ._somefile meta_data. Then I tar this. Note this trick winds up as an intermediate step, making a full copy of the folder you are trying to archive (it cleans up after itself), so don't do this on a nearly full disk! Also note that this script is for illustration purposes only and is not very general: it assumes that you are in the directory containing some_folder; it won't quite work if the you give it a full path to some_dir on the command line.

Okay now how do I un-tar-zip this and restore the resource forks? To do this, you need to un-tar-zip it then creates a cpio archive, then use ditto to unarchive this. Yuck, and this is left as an exercise to the reader. But better yet, just stick with the cpio archives.

Lastly I'll mention one final mystery that maybe some reader can solve. I ran into in figuring this out. If you look at the script above, I called one of the intermediate files TEMPFIFO. This is because in my original script i used a unix fifo instead of a real file and backgrounded the first ditto command, figuring I could save some space and time. Oddly, about every ten or so tries the first ditto command issues an error message about not being able to complete the fifo. I have no idea why that error would happen. Anyone know why? Also maybe someone would like to wrap this in apple script for a drag and drop and post it below?

Comments (19)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20031118111144197