views:

232

answers:

2

I want to distribute a cross-platform application for which the executable file is slightly different, depending on the user who downloaded it. This is done by having a placeholder string somewhere in the executable that is replaced with something user-specific upon download.

The webserver that has to do these string replacements is a Linux machine. For Windows, the executable is not compressed in the installer .exe, so the string replacement is easy.

For uncompressed Mac OS X .dmg files, this is also easy. However, .dmg files that are compressed with either gzip or bzip2 are not so easy. For example, in the latter case, the compressed .dmg is not one big bzip2-compressed disk image, but instead consists of a few different bzip2-compressed parts (with different block sizes) and a plist suffix. Also, decompressing and recompressing the different parts with bzip2 does not result in the original data, so I'm guessing Apple uses some different parameters to bzip2 than the command-line tool.

Is there a way to generate a compressed .dmg from an uncompressed one on Linux (which does not have hdiutil)? Or maybe another suggestion for creating customized applications without pregenerating them? It should work without any input by the user.

A: 

If your web server and client support the gzip encoding, then you can deal with uncompressed files on the server, but have them compressed / decompressed on the fly by the web server / web client respectively.

e.g. apache's mod_gzip.

Otherwise maybe you can split your dmg into 3 parts:

  • the stuff before what you want to replace
  • the string you want to replace
  • the stuff after what you want to replace

    If the gzip stream is splittable at those points, you could just concatenate the front and back onto the gzipped string you want to replace. That would let you generate it on the fly.

Peter Cordes
I decided to use hdiutil to create a readonly image (UDRO), which minimized the size but does not compress. For most users, it will be transmitted gzipped over HTTP and I guess I'll have to take the small disk space penalty.
Marten
Hmm, turns out this does not work because read-only images have checksums. And I can't use a read-write image because then OS X will not pop up the contents of the .dmg automatically when it is mounted.
Marten
A: 

Release a normal, read-only, compressed dmg. Then bundle your app in a package installer with a pre-flight script that sets the variables you need.

jkyle