Wednesday, 24 November 2004
A pax on the OS X Installer
One of the worst parts of Mac OS X is its installer. “Primitive” is being generous, especially when coming from the Mac OS 9 installer, which was wonderfully elegant in operation, if a bit confusing in both authoring and licensing from a developer standpoint. It’s been three major releases and there’s still no “uninstall” or “remove” option—both the former NeXT and Apple installers had one, so they really had no excuse. Worse, the package format isn’t designed for supporting package removal, so even if some hypothetical future installer were to support it, all the existing packages couldn’t be touched. We are left with rooting around on our filesystems ourselves, or using incomplete third-party solutions like DesInstaller. The installer is getting some major revisions for Tiger, from what I hear, so I hope the uninstallation problem is solved.
At the root of the installer problems is the use of pax as an archiving utility. Given that most installations do a lot more than just unpack some files in the filesystem, it is responsible for clobbering symlinks, corrupting permissions, disrespecting users’ moving and renaming of applications, and lots more. Everyone else in the Unix world uses tar instead of pax, but for some odd reason Apple had to be different. The pax tool is a pain to use, but I’ve discovered some convenient workarounds, to follow.
Sometimes I want to see what’s inside an installer package, or extract the files from it without running the installer proper. On Mac OS 9, Apple provided the convenient TomeViewer utility; OS X’s equivalent is lsbom and pax, or the $20 shareware Pacifist. But Pacifist isn’t much help if you’re just ssh’d into a machine, or if I’m on a computer without Pacifist installed. While trying to figure out pax’s obtuse syntax for the 3000th time last week, I noticed something interesting:
% gunzip Archive.pax.gz % file Archive.pax Archive.pax: ASCII cpio archive (pre-SVR4 or odc)
Hmm, cpio. I wonder…
% ditto -x Archive.pax.gz Archive % ls -l Archive total 0 drwxrwxr-x 4 nicholas admin 136 Nov 2 18:53 Library/ drwxr-xr-x 3 nicholas wheel 102 Nov 2 18:53 private/ drwxr-xr-x 4 nicholas wheel 136 Nov 2 18:54 usr/
Make sure to use sudo if you want ditto to preserve the installer creator’s intended permissions.
A lesser-known feature of Panther’s ditto is that it can produce and unpack cpio and ZIP-format archives. In the case of ZIP, it can even include the Mac metadata in the format the Finder (really BOMArchiveHelper)’s “Create Archive” command uses, with the --sequesterRsrc option. There’s lots of useful information about using ditto for archiving in this Mac OS X Hints article.
ditto has the -z option to indicate that the cpio archive is compressed, but it seems optional (as above); you can just use -x. ditto’s option parsing is brain dead anyway; despite its use of GNU-style long options it won’t take -zx; it wants -z -x.
From the Finder, you can pick “Show Package Contents” from the package’s contextual menu, navigate into the Contents folder, and invoke BOMArchiveHelper to extract the archive; just rename the .pax.gz file to .cpgz, acknowledge the stupid alert if necessary, and double-click. You can also rename .pax to .cpio if you uncompressed it first.
So, there you have it: two considerably more convenient ways to extract .pax.gz files. You still need to use pax or Pacifist (or cpio, I guess) if you’re dealing with a huge package and don’t want to extract every file in it.
By the way, if you’re still writing installers using Apple’s pitiful PackageMaker, go get Iceberg. It’s free, and terrific—what PackageMaker should have been.